Codeforces Round #148 (Div. 2) 【AK】
A:...比赛的时候居然写挂了。。。
1 #include<cstdio> 2 int main(){ 3 int y,k,n; 4 while(~scanf("%d%d%d",&y,&k,&n)){ 5 bool f=0; 6 for(int i=1;i*k<=n;i++){ 7 if(i*k>y){ 8 if(f)printf(" "); 9 printf("%d",i*k-y); 10 f=1; 11 } 12 } 13 if(f)puts(""); 14 else puts("-1"); 15 } 16 return 0; 17 }
B:...模拟。。。尼玛cf还出模拟玩。。。。
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #define N 110 5 using namespace std; 6 string s,ss; 7 int ll,rr; 8 int hash[N]; 9 bool x[N]; 10 int d; 11 void solve(int l,int pre){ 12 if(l<ll||l>rr)return ; 13 int pp=pre; 14 pre=l; 15 if(ss[l]>='0'&&ss[l]<='9'){ 16 hash[ss[l]-'0']++; 17 if(ss[l]!='0')ss[l]--; 18 else x[l]=0; 19 if(d==1){ 20 ++l; 21 while(l<=rr&&x[l]==0)++l; 22 // if(l>rr)return ; 23 solve(l,pre); 24 } 25 else{ 26 --l; 27 while(l>=ll&&x[l]==0)--l; 28 // if(l<ll)return ; 29 solve(l,pre); 30 } 31 } 32 else{ 33 if(ss[l]=='<')d=0; 34 else d=1; 35 if(pp!=l&&(ss[pp]=='>'||ss[pp]=='<')){ 36 x[pp]=0; 37 } 38 if(d==1){ 39 ++l; 40 while(l<=rr&&x[l]==0)++l; 41 // if(l>rr)return ; 42 solve(l,pre); 43 }else{ 44 --l; 45 while(l>=ll&&x[l]==0)--l; 46 // if(l<ll)return ; 47 solve(l,pre); 48 } 49 } 50 } 51 52 53 int main(){ 54 int n,q; 55 while(cin>>n>>q){ 56 cin>>s; 57 while(q--){ 58 int l, r; 59 cin>>l>>r; 60 ss=s; 61 d=1; 62 l--,r--; 63 memset(hash,0,sizeof(hash)); 64 memset(x,1,sizeof(x)); 65 ll=l,rr=r; 66 solve(l,l); 67 for(int i=0;i<=9;i++) 68 cout<<hash[i]<<" "; 69 cout<<endl; 70 } 71 } 72 return 0; 73 }
C:乘法原理,对于第i+1个位置,能选的方案只有2^m-i-i种。。。
1 #include<iostream> 2 using namespace std; 3 typedef long long ll; 4 const ll mod=(ll)1e9+9; 5 int main(){ 6 int n,m; 7 while(cin>>n>>m){ 8 ll a=1; 9 bool flag=0; 10 for(int i=1;i<=m;i++){ 11 a*=2; 12 a%=mod; 13 if(a>n)flag=1; 14 } 15 if(!flag) 16 cout<<0<<endl; 17 else{ 18 ll ans=1; 19 for(int i=1;i<=n;i++) 20 ans=(ans*(a-i)%mod+mod)%mod; 21 cout<<ans<<endl; 22 } 23 } 24 return 0; 25 }
D。给定一组数,现在将这些数分成两组,定义函数f(a[i],a[j]),
if(a[i]和a[j]同组) f(a[i],a[j]) = a[i] + a[j];
else f(a[i],a[j]) = a[i] + a[j] + h,
现在给定这些数和h,求解最优方案。。。
解法:想了两天不知道咋贪心,学习了一下别人的思路。。。
先将数组从小到大排序,最优方案一定在这样的安排方式之中,a[1],a[2]....a[k]一组,a[k+1],a[k+2]...a[n]一组,然后枚举k求解。。。
也就是说两组数中,数值的大小在原数组中一定是连续的,也就是说其中一个数组中最大值小于等于另一个数组中的最小值。
下面证明为什么这样选择是正确的:
先假设分好的序列不满足上述性质,既将a[1],a[2]....a[k-1],a[k+1]分成一组,将a[k],a[k+2]...a[n]分成另一组。
在原分配方案中,minn1=a[1]+a[2],maxn1=max(a[n]+a[n-1],a[n]+a[k]+h);
在此方案中,minn2=a[1]+a[2],maxn2=max(a[n]+a[n-1],a[n]+a[k+1]+h);
显然minn1==minn2,而maxn2>=maxn1,所以这种选择方式肯定不是最优的。。。
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #define N 200010 5 using namespace std; 6 struct S{ 7 int val,id; 8 }s[N]; 9 bool cmp(S a,S b){ 10 return a.val<b.val; 11 } 12 int ans[N]; 13 int main(){ 14 int n,h; 15 while(cin>>n>>h){ 16 for(int i=1;i<=n;i++){ 17 cin>>s[i].val; 18 s[i].id=i; 19 } 20 sort(s+1,s+1+n,cmp); 21 int mx,mn,w; 22 int minn=(1<<30); 23 for(int k=1;k<=n;k++){ 24 if(k==1){ 25 mn=min(s[1].val+s[k+1].val+h,s[k+1].val+s[k+2].val); 26 mx=max(s[n].val+s[n-1].val,s[n].val+s[1].val+h); 27 } 28 else if(k<n){ 29 mn=s[1].val+s[2].val; 30 mx=max(s[n].val+s[n-1].val,s[n].val+s[k].val+h); 31 } 32 else if(k==n){ 33 mn=s[1].val+s[2].val; 34 mx=s[n].val+s[n-1].val; 35 } 36 if(minn>mx-mn){ 37 minn=mx-mn; 38 w=k; 39 } 40 } 41 for(int i=1;i<=w;i++) 42 ans[s[i].id]=1; 43 for(int i=w+1;i<=n;i++) 44 ans[s[i].id]=2; 45 cout<<minn<<endl; 46 for(int i=1;i<=n;i++) 47 cout<<ans[i]<<" "; 48 cout<<endl; 49 } 50 return 0; 51 }
E. 树形dp,可以枚举每条边,切掉这条边之后在两棵树里面dp一下,然后取最优值。
思路和这个差不多吧。。。http://www.cnblogs.com/silver-bullet/archive/2012/11/06/2757381.html
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #define N 200010 6 using namespace std; 7 struct Edge{ 8 int next,val; 9 }; 10 int edge[N][2]; 11 vector<Edge>V[N]; 12 int dp[N][2]; 13 int ans; 14 void dfs1(int u,int pre,int r){ 15 dp[u][0]=0; 16 for(int i=0;i<V[u].size();i++){ 17 int son=V[u][i].next; 18 if(son==pre||son==r)continue; 19 dfs1(son,u,r); 20 dp[u][0]+=dp[son][0]+V[u][i].val; 21 } 22 } 23 void dfs2(int u,int pre,int i,int r){ 24 if(u==pre)dp[u][1]=dp[u][0]; 25 else{ 26 if(V[pre][i].val==1)dp[u][1]=dp[pre][1]-1; 27 else dp[u][1]=dp[pre][1]+1; 28 } 29 ans=min(ans,dp[u][1]); 30 for(int i=0;i<V[u].size();i++){ 31 int son=V[u][i].next; 32 if(son==pre||son==r)continue; 33 dfs2(son,u,i,r); 34 } 35 } 36 int main(){ 37 int n; 38 while(cin>>n){ 39 if(n==1){ 40 cout<<0<<endl; 41 continue; 42 } 43 for(int i=1;i<=n;i++) 44 V[i].clear(); 45 for(int i=1;i<n;i++){ 46 cin>>edge[i][0]>>edge[i][1]; 47 Edge E; 48 E.next=edge[i][1]; 49 E.val=0; 50 V[edge[i][0]].push_back(E); 51 E.next=edge[i][0]; 52 E.val=1; 53 V[edge[i][1]].push_back(E); 54 } 55 int minn=(1<<30); 56 for(int i=1;i<n;i++){ 57 int u=edge[i][0],v=edge[i][1]; 58 int ans1,ans2; 59 ans=(1<<30); 60 dfs1(u,u,v); 61 dfs2(u,u,-1,v); 62 ans1=ans; 63 ans=(1<<30); 64 dfs1(v,v,u); 65 dfs2(v,v,-1,u); 66 ans2=ans; 67 minn=min(ans1+ans2,minn); 68 } 69 cout<<minn<<endl; 70 } 71 return 0; 72 }