http://codeforces.com/contest/1082/problem/A
WA数发,因为默认为x<y = =
分情况讨论,直达 or x->1->y or x->n->y 取最小值。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 #define mp make_pair 6 #define pb push_back 7 #define pii pair<int,int> 8 //#define debug 9 int main(){ 10 #ifdef debug 11 ifstream cin("C:/Users/Administrator/Desktop/test/in.txt"); 12 #endif debug 13 LL t; 14 cin>>t; 15 while(t--){ 16 LL n,x,y,d; 17 cin>>n>>x>>y>>d; 18 if(abs(y-x)%d==0){ 19 cout<<abs(y-x)/d<<endl; 20 } 21 else{ 22 bool ok=0; 23 LL ans=99999999999; 24 if((y-1)%d==0){ 25 ok=1; 26 ans=min(ans,(y-1)/d+(LL)(ceil(1.0*(x-1)/d))); 27 } 28 if((n-y)%d==0){ 29 ok=1; 30 ans=min(ans,(n-y)/d+(LL)(ceil(1.0*(n-x)/d))); 31 } 32 if(ok==0){ 33 cout<<-1<<endl; 34 } 35 else{ 36 cout<<ans<<endl; 37 } 38 } 39 } 40 return 0; 41 }
http://codeforces.com/contest/1082/problem/B
预处理G个数的前后缀长度,然后枚举所有S,考虑交换能达到的最大值。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 #define mp make_pair 6 #define pb push_back 7 #define pii pair<int,int> 8 //#define debug 9 void f(){ 10 char s[100010]; 11 int l[100010]={0},r[100010]={0}; 12 int n,G=0,S=0,ans=0; 13 cin>>n>>s+1; 14 for(int i=1;i<=n;++i){ 15 if(s[i]=='S') l[i]=0,S++; 16 else l[i]=l[i-1]+1,G++; 17 if(l[i]>ans)ans=l[i]; 18 } 19 r[n+1]=0; 20 for(int i=n;i>=1;--i){ 21 if (s[i]=='S') r[i]=0; 22 else r[i]=r[i+1]+1; 23 } 24 if(S<2){ 25 cout<<n-S<<endl; 26 return; 27 } 28 for(int i=1;i<=n;++i){ 29 if(s[i]=='S'){ 30 ans=max(ans,l[i-1]+r[i+1]+1); 31 } 32 } 33 if(ans>G)ans=G; 34 cout<<ans<<endl; 35 36 } 37 int main(){ 38 #ifdef debug 39 ifstream cin("C:/Users/Administrator/Desktop/test/in.txt"); 40 #endif debug 41 f(); 42 return 0; 43 }
http://codeforces.com/contest/1082/problem/C
C的题意是给出n个人的专长(m种)si和对应的熟练度ri,挑出一部分人组成一个团体,要求团体中每个不同的专长对应的人数一致。求使得团队熟练度总和最大是多少。
对专长进行分类,然后按照熟练度降序求前缀和。然后枚举不同专长对应的人数即可,需要注意的是有一个优化是对专长人数进行降序排列后再进行查找会节省很多时间,因为当到达某个专长时的人数不足以满足,可以及时的break。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 #define mp make_pair 6 #define pb push_back 7 #define pii pair<int,int> 8 //#define debug 9 LL s[100010],r[100010],x[100010]; 10 std::vector<LL> v[100010]; 11 bool cmp(int i,int j){ 12 return v[i].size()>v[j].size(); 13 } 14 int main(){ 15 #ifdef debug 16 ifstream cin("C:/Users/Administrator/Desktop/test/in.txt"); 17 #endif debug 18 LL n,m; 19 cin>>n>>m; 20 //for(int i=1;i<=m;++i)v[i].push_back(0); 21 for(int i=1;i<=n;++i){ 22 //cin>>s[i]>>r[i]; 23 scanf("%lld%lld",s+i,r+i); 24 v[s[i]].push_back(r[i]); 25 } 26 int maxn=0; 27 for(int i=1;i<=m;++i){ 28 sort(v[i].begin(),v[i].end(),greater<LL>()); 29 maxn=max(maxn,(int)(v[i].size())); 30 } 31 LL ans=0; 32 for(int i=1;i<=m;++i){ 33 x[i]=i; 34 for(int j=1;j<v[i].size();++j){ 35 v[i][j]+=v[i][j-1]; 36 } 37 } 38 sort(x+1,x+1+m,cmp); 39 for(int i=1;i<=maxn;++i){ 40 LL tmp=0; 41 for(int j=1;j<=m&&v[x[j]].size()>=i;++j){ 42 if(v[x[j]][i-1]>0) tmp+=v[x[j]][i-1]; 43 } 44 if(tmp>ans)ans=tmp; 45 } 46 cout<<ans<<endl; 47 return 0; 48 }
http://codeforces.com/contest/1082/problem/D
D题的题意是给出n个点以及他们的度数,询问是否可以构造出一幅无自环无重边的无向图且使得任意两点最短距离的最大值尽可能的大。
其实是个很简单的构造题,按照度数降序排列之后,先尽可能的组成一条链,然后看看剩下的孤独点是否可以加在树上即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 #define mp make_pair 6 #define pb push_back 7 #define pii pair<int,int> 8 struct node 9 { 10 int id,a; 11 }x[555]; 12 bool cmpa(node A,node B){return A.a>B.a;} 13 std::vector<int> g[555]; 14 void add(int i,int j){ 15 g[i].push_back(j); 16 g[j].push_back(i); 17 } 18 int main(){ 19 int n,i,j,m=0; 20 cin>>n; 21 for(i=1;i<=n;++i){ 22 x[i].id=i; 23 cin>>x[i].a; 24 } 25 sort(x+1,x+1+n,cmpa); 26 int l=0; 27 for(i=2;i<=n;i++){ 28 x[i].a--,x[i-1].a--; 29 add(x[i].id,x[i-1].id); 30 m++; 31 l++; 32 if(x[i].a==0)break; 33 } 34 int md=i++; 35 int o=0; 36 while(i<=n){ 37 bool ok=0; 38 for(j=1;j<=md;++j){ 39 if(x[j].a>=1){ 40 o=1; 41 ok=1; 42 x[j].a--; 43 x[i].a--; 44 add(x[i].id,x[j].id); 45 i++;m++; 46 break; 47 } 48 } 49 if(!ok)break; 50 } 51 l+=o; 52 if(i<=n){puts("NO");} 53 else{ 54 cout<<"YES "<<l<<endl; 55 cout<<m<<endl; 56 for(i=1;i<=n;++i){ 57 for(j=0;j<g[i].size();++j){ 58 if(g[i][j]>i){ 59 cout<<i<<' '<<g[i][j]<<endl; 60 } 61 } 62 } 63 } 64 return 0; 65 }