标签:acm 编程 算法 codeforces
A - Maximum in Table
纯递推。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> using namespace std; #define LL __int64 #define pi acos(-1.0) const int mod=1e9+7; const int INF=0x3f3f3f3f; const double eqs=1e-9; int a[12][12]; int main() { int n, i, j; scanf("%d",&n); for(i=0;i<n;i++){ a[i][0]=1; a[0][i]=1; } for(i=1;i<n;i++){ for(j=1;j<n;j++){ a[i][j]=a[i-1][j]+a[i][j-1]; } } printf("%d\n",a[n-1][n-1]); return 0; }
第一次读错题了,看成相邻的两个任意两种颜色不超过1了。。是任意的两个都要满足。最简答的方法是对于c[i][j]输出(j-1)%k+1就行了。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> using namespace std; #define LL __int64 #define pi acos(-1.0) const int mod=1e9+7; const int INF=0x3f3f3f3f; const double eqs=1e-9; int a[120]; int main() { int n, k, i, j, flag; while(scanf("%d%d",&n,&k)!=EOF) { flag=0; for(i=0; i<n; i++) { scanf("%d",&a[i]); } for(i=0;i<n;i++){ for(j=0;j<i;j++){ if(a[i]-a[j]>k||a[j]-a[i]>k){ flag=1; break; } } if(flag) break; } if(flag) { puts("NO"); } else { puts("YES"); for(i=0; i<n; i++) { for(j=1; j<=a[i]; j++) { printf("%d ",(j-1)%k+1); } puts(""); } } } return 0; }
贪心+构造。
思路很容易想出来,但是细节不好实现,错了好多次才AC。
大体思路是,先构造出最小的a[0]。
然后假如b[i]>b[i-1],那么就从低位向高位贪心构造,只要还没填满到9,就继续填满,直到填到9或者总共填了b[i]-b[i-1]为止。
假如b[i]<=b[i-1],那么先从低位到高位遍历,找到第一个到最低位的数字和大于b[i-1]-b[i]的位而且该位不能为9,然后从当前位到最低位的所有数字进行重新构造,高位的保留。
下面的代码是比赛时AC的代码,有一些冗杂的地方,试着优化了一下,结果样例都不过了。。于是也懒得优化了。。就贴上了。。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> using namespace std; #define LL __int64 #define pi acos(-1.0) const int mod=1e9+7; const int INF=0x3f3f3f3f; const double eqs=1e-9; int b[400], len; int a[1000], c[1000]; int main() { int n, i, j, x, cnt, sum; while(scanf("%d",&n)!=EOF){ for(i=0;i<n;i++){ scanf("%d",&b[i]); } x=b[0]; cnt=0; memset(a,0,sizeof(a)); while(x){ if(x>=9){ x-=9; c[cnt++]=9; }else { c[cnt++]=x; x=0; } } for(i=cnt-1;i>=0;i--){ printf("%d",c[i]); a[i]=c[i]; } len=cnt; puts(""); for(i=1;i<n;i++){ if(b[i]>b[i-1]){ x=b[i]-b[i-1]; for(j=0;;j++){ if(9-a[j]>=x){ a[j]+=x; x=0; }else{ x-=9-a[j]; a[j]=9; } if(!x) break; } len=max(j+1,len); } else{ x=b[i-1]-b[i]; sum=0; int pos, y; for(j=0;;j++){ if(sum+a[j]>x){ pos=j+1; y=sum+a[j]-x-1; a[j]=0; break; } else{ sum+=a[j]; a[j]=0; } //sum+=a[j]; } while(a[pos]==9){ pos++; } y=a[pos]+1; a[pos]=y; x=0; for(j=len-1;j>pos;j--){ x+=a[j]; } x=b[i]-a[pos]-x; for(j=0;j<pos;j++){ if(x>9){ a[j]=9; x-=9; } else{ a[j]=x; x=0; } } len=max(pos+1,len); } for(j=len-1;j>=0;j--){ printf("%d",a[j]); } puts(""); } } return 0; }
这题其实比C题简单,但是当时C调试了好长时间,导致最后E题没时间写了。
这题就是根据每个位置在所有子序列中的贡献值推出公式,然后求那个公式就可以了。公式是有规律的。提前预处理一下,然后再遍历每个位置,加加减减就行了。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> using namespace std; #define LL __int64 #define pi acos(-1.0) const int mod=1e9+7; const int INF=1e9; const double eqs=1e-9; char s[1000000]; double sum[1000000], ssum[1000000]; bool Judge(char c) { if(c=='A'||c=='E'||c=='I'||c=='O'||c=='U'||c=='Y') return 1; return 0; } int main() { int len, i, j, tmp; double ans; while(scanf("%s",s)!=EOF){ len=strlen(s); sum[0]=0; ssum[0]=0; for(i=1;i<=len;i++){ sum[i]=sum[i-1]+1.0/i; ssum[i]=ssum[i-1]+(len-i+1)*1.0/i; //printf("%d\n",len-i+1); } ans=0; for(i=1;i<=len;i++){ if(Judge(s[i-1])){ tmp=i; if(i>len/2) tmp=len-i+1; ans+=tmp+ssum[len]-ssum[len-tmp]+tmp*(sum[len-tmp]-sum[tmp]); } } printf("%.7f\n",ans); } return 0; }
Codeforces Round #289 Div. 2 解题报告 A.B.C.E
标签:acm 编程 算法 codeforces
原文地址:http://blog.csdn.net/scf0920/article/details/43406027