Codeforces Round #148 (Div. 2) 【AK】

A:...比赛的时候居然写挂了。。。

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还出模拟玩。。。。

B
 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种。。。

C
 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,所以这种选择方式肯定不是最优的。。。

D
 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

E
 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 }

 

 

 

posted @ 2012-11-06 13:48  silver__bullet  阅读(253)  评论(0编辑  收藏  举报