Codeforces Round #145 (Div. 2, ACM-ICPC Rules)
C. Weath
水,暴力确定正数的起点,有DP的手法计算消耗即可
#include<stdio.h> #define eps 1e8 #define LMT 1000005 //知道这题很弱。 //你要先选择一个正数的起点,然后会有各种消耗,算消耗是可以用DP int temp[LMT],dp[LMT],rdp[LMT]; int main(void) { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); int i,n,ans; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d",&temp[i]); if(i>0) dp[i]=dp[i-1]+(temp[i-1]>=0); } ans=eps; for(i=n-1;i>=0;i--) { rdp[i]=rdp[i+1]+(temp[i]<=0); dp[i]+=rdp[i]; if(i>0) ans=dp[i]>ans?ans:dp[i]; } printf("%d\n",ans); return 0; }
Codeforces Round #143 (Div. 2) B. Magic, Wizardry and Wonders
#include<stdio.h> /*注意这种只有去一种的题,用怪想法。让A[I]取值范围最宽 极端取值法,最好K为0,这样什么都不用管了,要尽可能长久的取到某数,贪心,递推能力不够*/ int main(void) { int a[105]; int n,l,d,i; scanf("%d%d%d",&n,&d,&l); for(i=1;i<n;i++) { if(d>0)a[i]=l; else a[i]=1; d=a[i]-d; } a[n]=d; if(a[n]<=0||a[n]>l)printf("-1\n"); else { for(i=1;i<=n;i++) printf("%d ",a[i]); printf("\n"); } return 0; }
Codeforces Round #139 (Div. 2) C. Barcode
基本DP,确定最长与最短无后效性的位置,黑白相间段落的基本技能
#include<stdio.h> #include<string.h> #define LMT 1002 //往后指,确定长度,黑白段DP int sum[LMT][2],dp[LMT][2]; int main() { int n,m,x,y,i,j; char c; memset(dp,-1,sizeof(dp)); scanf("%d%d%d%d",&n,&m,&x,&y);getchar(); sum[0][1]=sum[0][0]=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { c=getchar(); if(c=='.') sum[j][0]++; else sum[j][1]++; } getchar(); } for(i=1;i<=m;i++) { sum[i][1]+=sum[i-1][1]; sum[i][0]+=sum[i-1][0]; } dp[0][0]=dp[0][1]=0; for(i=x;i<=m;i++)//写主体的时候不要前功尽弃... for(j=i-x;j>=0&&j>=i-y;j--) { if(dp[j][1]!=-1) { if(dp[j][1]+sum[i][0]-sum[j][0]<dp[i][0]||dp[i][0]==-1) dp[i][0]=dp[j][1]+sum[i][0]-sum[j][0]; } if(dp[j][0]!=-1) { if(dp[j][0]+sum[i][1]-sum[j][1]<dp[i][1]||dp[i][1]==-1) dp[i][1]=dp[j][0]+sum[i][1]-sum[j][1]; } } printf("%d\n",dp[m][1]>dp[m][0]?dp[m][0]:dp[m][1]); return 0; }
Codeforces Round #135 (Div. 2) C. Color Stripe
其实一开始的想法是对的,主要没有考虑两种颜色的情况
#include<stdio.h> #define LMT 500005 char s[LMT]; int n,k,p1,p2; //注意对小数据的检查 //贪心就是乱搞 int main(void) { int i; scanf("%d%d%s",&n,&k,s); if(k==2) { for(i=0;i<n;i++) { if(s[i]-'A'!=i%2)p1++; else p2++; } printf("%d\n",p1<p2?p1:p2); if(p1>p2) for(i=0;i<n;i++)printf("%c",'A'+(i+1)%2); else for(i=0;i<n;i++)printf("%c",'A'+i%2); printf("\n"); } else { int ans=0; for(i=2;i<n;i++) { if(s[i-2]==s[i-1]) { s[i-1]='A'; while(s[i-1]==s[i]||s[i-2]==s[i-1])s[i-1]++; ans++; } } if(s[n-2]==s[n-1]) { s[n-1]='A'; while(s[n-2]==s[n-1])s[n-1]++; ans++; } printf("%d\n%s\n",ans,s); } return 0; }
Codeforces Round #135 (Div. 2)A. k-String
#include<iostream> #include<string> using namespace std; //纯暴力手法,没有想象力啊,跟踪解法... //如果两个字串直接有公共元素,那么,把他们联合起来,那个元素在任何位置都可以符合题意 //记得联合法 //随意暴力出一个元素,然后进行配对,有C++写吧,被跪类.. string s,s1,s2; int jud(int i,int time) { int p,t; for(p=0;p<=i;p++) for(t=1;t<time;t++)//这个字符串里最多可以承受几个元素,t<time代表有time个 if(s[p]!=s[p+t*(i+1)]) return 0; return 1; } int main(void) { cin>>s1>>s2; int i,j,ans,l1=s1.size(),l2=s2.size(); s=s1+s2; i=0;ans=0; while(i<l1&&i<l2) { if(l1%(i+1)==0&&l2%(i+1)==0) { j=(l1+l2)/(i+1); if(jud(i,j))ans++; } i++; } cout<<ans<<endl; return 0; }