Codeforces Round #228 (Div. 2) D - Fox and Minimal path

2024-05-29 07:38

本文主要是介绍Codeforces Round #228 (Div. 2) D - Fox and Minimal path,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前三题 没有什么可以说的 水题, 但是 B题 大意了,最后WA了,所以 rating 大降 T_T. 

何时才能进DIV1 啊。 

D题, 当时 交了一发,不过被HACK了,因为考虑不全面。 当时的想法是把 K 分解为1000 内的因数相乘 而且 这些因数的和<=1000。这样显然是不正确的,因为可能根本找不到这些符合条件的因数。

之后,考虑分解为二进制,之后是相乘之积 相加。上面的错误之处也就是在于全是相乘。

用这个思路分解,比如用二进制分解  K=5, 可以这么构造k=5=2*2+1*1;

 又在赛后写了一发, 在一个28个1的二进制的数上过不去, 经过计算,这样的构造方法会使节点的数目超过1000.   

所以考虑其他进制的分解,可以粗略算得  十进制的构造方法最糟不会超过800多节点,故可行。 10进制的方法和二进制思路一样。

code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 1000000000
#define N 1005
int n,k;
bool vis[N][N];
char s[100];
int main()
{scanf("%d",&k);sprintf(s,"%d",k);int len=strlen(s);memset(vis,0,sizeof(vis));int now=2,last;for(int i=0;i<len;i++){int tmp=s[i]-'0';if(!tmp) continue;for(int j=1;j<=tmp;j++){vis[1][now+j]=vis[now+j][1]=1;}last=now;now+=tmp;int need=len-i-1;for(int j=1;j<=need;j++){last=now;if(j==1){for(int p=now-tmp+1;p<=now;p++)for(int q=now+1;q<=now+10;q++)vis[p][q]=vis[q][p]=1;}else{for(int p=now-9;p<=now;p++)for(int q=now+1;q<=now+10;q++)vis[p][q]=vis[q][p]=1;}now+=10;}if(i==0){for(int q=last+1;q<=now;q++)  vis[q][2]=vis[2][q]=1;}for(int j=1;j<=i;j++){if(j==1){for(int p=last+1;p<=now;p++) vis[p][now+1]=vis[now+1][p]=1;now++;}else{vis[now][now+1]=vis[now+1][now]=1;now++;}if(j==i) vis[now][2]=vis[2][now]=1;}}printf("%d\n",now);for(int i=1;i<=now;i++){for(int j=1;j<=now;j++){if(vis[i][j]) printf("Y");else printf("N");}puts("");}return 0;
}

 ----------------------------------------------------------------------------------------------------------------------------------

额 , 发现 二进制分解构造 是可行的 , 而且 结果会更优 , 不会超过100 个点的。

比如 , K=12;  1110(二进制)


除去 1  2 两点 分为 3层,列数决定于 二进制的位数,前2层构造完成,就构造出了最高位的方案数 样例中的8种。 再构造出 4+2 种就完成了。

就如图,连接红色的边,就完成了。  如果需要1种,就把 1 点 和左下角的点连接即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 1000000000
#define N 1005
int k,n;
bool vis[N][N];
int m[N],ad,mark,now=2;
void sol()
{if(mark==0){vis[1][2]=vis[2][1]=1; return ;}vis[1][4]=vis[1][5]=vis[4][1]=vis[5][1]=1;for(int i=2;i<=mark;i++){vis[i*3+1][i*3-2]=vis[i*3-2][i*3+1]=vis[i*3+2][i*3-1]=vis[i*3-1][i*3+2]=1;vis[i*3+2][i*3-2]=vis[i*3-2][i*3+2]=vis[i*3+1][3*i-1]=vis[i*3-1][i*3+1]=1;vis[i*3][i*3-3]=vis[i*3-3][i*3]=1;}vis[mark*3][2]=vis[2][mark*3]=vis[mark*3+1][2]=vis[2][mark*3+1]=vis[mark*3+2][2]=vis[2][mark*3+2]=1;for(int i=0;i<mark;i++){if(m[i] & (!i) ){vis[1][3]=vis[3][1]=1; continue;}if(m[i]) vis[3*i+3][3*i+1]=vis[3*i+1][3*i+3]=vis[3*i+3][3*i+2]=vis[3*i+2][3*i+3]=1;}now+=mark*3;
}
int main()
{scanf("%d",&k);memset(vis,0,sizeof(vis));ad=-1;for(int i=0;i<=31;i++){int tmp=(k>>i)&1;m[++ad]=tmp;}for(int i=32;i>=0;i--){if(m[i]){mark=i; break;}}sol();printf("%d\n",now);for(int i=1;i<=now;i++){for(int j=1;j<=now;j++){printf("%c",vis[i][j]==1? 'Y':'N');}puts("");}return 0;
}


这篇关于Codeforces Round #228 (Div. 2) D - Fox and Minimal path的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1013048

相关文章

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

CSS实现DIV三角形

本文内容收集来自网络 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;} #triangle-down {width: 0;height: 0;bor

创建一个大的DIV,里面的包含两个DIV是可以自由移动

创建一个大的DIV,里面的包含两个DIV是可以自由移动 <body>         <div style="position: relative; background:#DDF8CF;line-height: 50px"> <div style="text-align: center; width: 100%;padding-top: 0px;"><h3>定&nbsp;位&nbsp;

Codeforces Round 971 (Div. 4) (A~G1)

A、B题太简单,不做解释 C 对于 x y 两个方向,每一个方向至少需要 x / k 向上取整的步数,取最大值。 由于 x 方向先移动,假如 x 方向需要的步数多于 y 方向的步数,那么最后 y 方向的那一步就不需要了,答案减 1 代码 #include <iostream>#include <algorithm>#include <vector>#include <string>

Minimal coverage -uva 覆盖线段,贪心

一道经典的贪心问题,具体方法就是将(an,bn)区间,按照an从小到大的顺序进行排序,之后从0开始, 取最大的有效区间,这里用到了结构体的快排,否则可能会超时. #include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 100000 + 10#define BOTTOM -50000 - 10str

CF#271 (Div. 2) D.(dp)

D. Flowers time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/474/problem/D We s