Codeforces Round #376 (Div. 2)

 链接:http://codeforces.com/contest/731

感觉自己好菜啊,这么简单的题都没AK。。。还有它为什么不按套路出牌啊,F题比E题简单。。。

A题:大水题,模拟,不说了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 int n,ans;
 8 char s[105];
 9 int read(){
10     int x=0,f=1;char ch;
11     for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
12     for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
13     return x*f;
14 }
15 int main(){
16     scanf("%s",s+1);n=strlen(s+1);
17     char p='a';
18     for(int i=1;i<=n;i++){
19         int xx=abs(s[i]-p);
20         ans+=min(xx,26-xx);
21         p=s[i];
22     }
23     printf("%d\n",ans);
24     return 0;
25 }
View Code

B题:也是大水题。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 int n,a[200005];
 8 int read(){
 9     int x=0,f=1;char ch;
10     for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
11     for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
12     return x*f;
13 }
14 int main(){
15     n=read();
16     for(int i=1;i<=n;i++)a[i]=read();
17     for(int i=1;i<=n;i++){
18         if(a[i]<0){puts("NO");return 0;}
19         else{
20             a[i]%=2;if(a[i])a[i]--,a[i+1]--;
21         }
22     }
23     if(a[n+1]<0)puts("NO");
24     else puts("YES");
25     return 0;
26 }
View Code

C题:就是找出同一个联通块中出现最多的颜色的出现次数。。。我还傻逼的写了一个线段树。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 typedef double ld;
 9 typedef unsigned long long ull;
10 int n,m,k,tot,num,cnt,fa[200005],a[200005],h[200005],way[200005*2],fuck[200005*2],sum[200005],t[200005*4],v[200005];
11 int ans;
12 int read(){
13     int x=0,f=1;char ch;
14     for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
15     for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
16     return x*f;
17 }
18 void insert(int x,int y){way[++tot]=y;fuck[tot]=h[x];h[x]=tot;}
19 void change(int z,int l,int r,int x,int y){
20     if(l>x||r<x)return;
21     if(l==r){t[z]+=y;return;}
22     int mid=(l+r)>>1;
23     change(z<<1,l,mid,x,y);change(z<<1|1,mid+1,r,x,y);
24     t[z]=max(t[z<<1],t[z<<1|1]);
25 }
26 void dfs(int x,int y,int fa){
27     v[x]=cnt;change(1,1,k,a[x],y);num++;
28     for(int j=h[x];j;j=fuck[j])if(way[j]!=fa&&v[way[j]]!=cnt){
29         dfs(way[j],y,x);
30     }
31 }
32 int main(){
33     n=read();m=read();k=read();
34     for(int i=1;i<=n;i++)a[i]=read();
35     for(int i=1,x,y;i<=m;i++){
36         x=read();y=read();
37         insert(x,y);insert(y,x);
38     }
39     for(int i=1;i<=n;i++)if(h[i]&&!v[i]){
40         num=0;cnt++;dfs(i,1,0);ans+=num-t[1];cnt++;dfs(i,-1,0);
41     }
42     printf("%d\n",ans);
43     return 0;
44 }
View Code

D题:考虑找出使相邻两个词按字典序排列的答案范围,求一下交集就好了。。。然而我还是傻逼的写了个线段树。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define maxn 500005
 7 #define maxc 1000005
 8 using namespace std;
 9 int n,c,a[maxn],b[maxn],t[maxc*4],bj[maxc*4];
10 int read(){
11     int x=0,f=1;char ch;
12     for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
13     for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
14     return x*f;
15 }
16 void down(int z,int l,int r){
17     if(bj[z]!=-1&&l!=r){
18         t[z<<1]=bj[z];t[z<<1|1]=bj[z];
19         bj[z<<1]=bj[z];bj[z<<1|1]=bj[z];
20     }
21     bj[z]=-1;
22 }
23 void change(int z,int l,int r,int x,int y,int w){
24     if(x>y)return;
25     if(l>y||r<x)return;
26     down(z,l,r);
27     if(l>=x&&r<=y){t[z]=w;bj[z]=w;return;}
28     int mid=(l+r)>>1;
29     change(z<<1,l,mid,x,y,w);change(z<<1|1,mid+1,r,x,y,w);
30     t[z]=t[z<<1]|t[z<<1|1];
31 }
32 int query(int z,int l,int r){
33     down(z,l,r);
34     if(t[z]==0)return -1;
35     if(l==r)return l;
36     int mid=(l+r)>>1;
37     if(t[z<<1])return query(z<<1,l,mid);
38     else query(z<<1|1,mid+1,r);
39 }
40 int main(){
41     n=read();c=read();
42     memset(bj,-1,sizeof(bj));
43     for(int i=1;i<=4*c;i++)t[i]=1;
44     a[0]=read();for(int i=1;i<=a[0];i++)a[i]=read();
45     for(int i=2;i<=n;i++){
46         b[0]=read();for(int j=1;j<=b[0];j++)b[j]=read();
47         for(int j=1;j<=a[0];j++){
48             if(j>b[0]){change(1,0,c-1,0,c-1,0);break;}
49             if(a[j]!=b[j]){
50                 int x=a[j],y=b[j];
51                 if(x<y)change(1,0,c-1,c-y+1,c-x,0);
52                 else change(1,0,c-1,0,c-x,0),change(1,0,c-1,c-y+1,c-1,0);
53                 break;
54             }
55         }
56         for(int j=0;j<=b[0];j++)a[j]=b[j];
57     }
58     printf("%d\n",query(1,0,c-1));
59     return 0;
60 }
View Code

E题:设dp[i]代表1~i-1都被取完时,先手与后手的最大得分差,dp[i]=max(sum[j]-dp[j])(j>i),答案即为dp[1]。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define maxn 200005
 7 using namespace std;
 8 typedef long long ll;
 9 typedef double ld;
10 typedef unsigned long long ull;
11 const ll inf=1e18;
12 int n,m;
13 ll a[maxn],ans;
14 int read(){
15     int x=0,f=1;char ch;
16     for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
17     for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
18     return x*f;
19 }
20 int main(){
21     n=read();
22     for(int i=1;i<=n;i++)a[i]=read();
23     for(int i=1;i<=n;i++)a[i]+=a[i-1];
24     ans=a[n];
25     for(int i=n-1;i>1;i--)ans=max(ans,a[i]-ans);
26     printf("%I64d\n",ans);
27     return 0;
28 }
View Code

F题:枚举选择的数i,再枚举j表示减完后是什么数,统计答案即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define maxn 1000005
 7 using namespace std;
 8 typedef long long ll;
 9 typedef double ld;
10 typedef unsigned long long ull;
11 int n,m,a[maxn],f[maxn];
12 ll ans,sum;
13 int read(){
14     int x=0,f=1;char ch;
15     for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
16     for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
17     return x*f;
18 }
19 int main(){
20     n=read();
21     for(int i=1,x;i<=n;i++){
22         x=read();a[x]++;
23     }
24     for(int i=200000;i;i--)f[i]=f[i+1]+a[i];
25     for(int i=1;i<=200000;i++)if(a[i]){
26         sum=0;
27         for(int j=i;j<=200000;j+=i)sum+=(ll)(f[j]-f[j+i])*j;
28         ans=max(ans,sum);
29     }
30     printf("%I64d\n",ans);
31     return 0;
32 }
View Code

 

posted @ 2016-10-17 08:52  I'mLS  阅读(117)  评论(0编辑  收藏  举报