The 2021 CCPC Guilin Onsite【A,I,G(二分),D(思维+构造),E(最短路】
https://codeforces.com/gym/103409
A(简单签到)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define int long long 6 #define pb push_back 7 #define N 300900 8 9 int n,arr[N]; 10 vector<int> v; 11 signed main(){ 12 int t; 13 cin>>t; 14 while(t--){ 15 cin>>n; 16 cout<<2*n-1<<endl; 17 } 18 19 return 0; 20 }
I
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define int long long 6 #define pb push_back 7 8 const int N = 1e6+100; 9 10 int n,arr[N]; 11 map<int,int> mp; 12 vector<int> v; 13 char s[N]; 14 signed main(){ 15 int t; 16 cin>>t; 17 while(t--){ 18 int ans=0; 19 cin>>n>>(s+1); 20 int sum=0; 21 v.clear(); 22 mp.clear(); 23 for(int i=n;i>=1;i--){ 24 if(s[i]=='0') sum++; 25 else{ 26 if(sum>0){ 27 sum--; 28 mp[i]=1; 29 ans+=i; 30 } 31 } 32 } 33 for(int i=n;i>=1;i--){ 34 if(s[i]=='1'){ 35 if(!mp[i]){ 36 v.pb(i); 37 } 38 } 39 } 40 for(int i=0;i<v.size();i+=2){ 41 if(i+1<v.size()) 42 ans+=v[i+1]; 43 } 44 cout<<ans<<endl; 45 } 46 47 return 0; 48 }
二分最小次数,每次check答案。找1的所在的位置,记录前面0的个数,如果当前二分的答案值小于前面0的个数,则不符合。若等于,则前面可以都处理,并且还可以占领后面(num-1)个数。若大于,则可以占领后面(num)个数。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define int long long 6 7 #define pb push_back 8 9 const int N = 1e6+100; 10 11 int n,arr[N]; 12 char str[N]; 13 bool check(int num){ 14 int id=0; 15 int sum=0,tmp=0; 16 int F=1; 17 for(int i=1;i<=n;i++){ 18 if(str[i]=='0'){ 19 if(i>id) 20 sum++; 21 else 22 sum=0; 23 }else{ 24 if(num==sum){ 25 sum=0; 26 id=max(id,i+num-1); 27 }else if(num>sum){ 28 sum=0; 29 id=max(id,i+num); 30 }else{ 31 F=0; 32 break; 33 } 34 } 35 } 36 if(F&&id>=n) return true; 37 else return false; 38 } 39 signed main(){ 40 int T=1; 41 cin>>T; 42 while(T--){ 43 cin>>n>>(str+1); 44 int tot=0; 45 for(int i=1;i<=n;i++){ 46 if(str[i]=='1') tot++; 47 } 48 if(tot==n){ 49 cout<<"0"<<endl;continue; 50 } 51 if(tot==0){ 52 53 cout<<n<<endl; 54 continue; 55 } 56 int l=0,r=n; 57 int ans=n; 58 //cout<<check(2)<<endl; 59 while(l<=r){ 60 int mid=(l+r)/2; 61 if(check(mid)){ 62 r=mid-1; 63 ans=min(ans,mid); 64 }else{ 65 l=mid+1; 66 } 67 } 68 cout<<ans<<endl; 69 } 70 return 0; 71 } 72 /* 73 15 74 100100001111110 75 */ 76 /* 77 11 78 100100001111110 79 */ 80 81 /* 82 24 83 10000000100100000000001 84 */
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int a[3000]; 6 int b[3000]; 7 int m[3000]; 8 int jishu=0; 9 struct node{ 10 int x,y; 11 }node[5000000]; 12 inline void write(int x) 13 { 14 char F[200]; 15 int tmp=x>0?x:-x ; 16 if(x<0)putchar('-') ; 17 int cnt=0 ; 18 while(tmp>0) 19 { 20 F[cnt++]=tmp%10+'0'; 21 tmp/=10; 22 } 23 while(cnt>0)putchar(F[--cnt]) ; 24 } 25 signed main(){ 26 int T ; 27 scanf("%d",&T); 28 while(T--){ 29 jishu=0; 30 int n; 31 scanf("%d",&n); 32 int sum=0; 33 for(int i=1;i<=n;i++){ 34 scanf("%d",&a[i]); 35 } 36 for(int i=1;i<=n;i++){ 37 scanf("%d",&b[i]); 38 m[b[i]]=i; 39 } 40 int flag=0; 41 for(int i=1;i<=n;i++){ 42 if(b[m[a[i]]]<b[i]){ 43 flag=1; 44 break; 45 } 46 else if(b[m[a[i]]]==b[i]){ 47 continue; 48 } 49 else{ 50 int pp=b[i]; 51 vector<int> q; 52 q.clear(); 53 for(int j=i;j<=m[a[i]];j++){ 54 if(b[j]>=pp&&b[j]<=a[i]){ 55 q.push_back(j); 56 pp=b[j]; 57 } 58 } 59 int tt=b[q[q.size()-1]]; 60 int len=q.size(); 61 for(int k=q.size()-1;k>=1;k--){ 62 b[q[k]]=b[q[k-1]]; 63 m[b[q[k-1]]]=q[k]; 64 sum++; 65 node[jishu].x=q[k]; 66 node[jishu++].y=q[k-1]; 67 } 68 b[q[0]]=tt; 69 m[tt]=q[0]; 70 } 71 } 72 if(flag==1){ 73 printf("-1\n"); 74 } 75 else{ 76 printf("%d\n",sum); 77 for(int i=jishu-1;i>=0;i--){ 78 printf("%d %d\n",node[i].y,node[i].x); 79 } 80 } 81 } 82 return 0; 83 }
猜个结论。答案只能0,1,2这3个数。如果一条边都买不起,则直接输出0.如果图中存在环路并能买的起,则输出2.否则输出1.(找环路可以用最短路实现)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 #define pb push_back 5 #define int long long 6 const int N = 2e3+100 , M = 5e3+100 , inf = 0x3f3f3f3f; 7 struct node{ 8 int v,w; 9 bool operator < (const node &t) const 10 { 11 return w>t.w; 12 } 13 }; 14 int n,m,c; 15 int u[M],v[M],p[M]; 16 vector<node> g[N]; 17 int vis[N]; 18 int dis[N][N]; 19 void dijkstra(int s){ 20 for(int i=1;i<=n;i++) vis[i]=0,dis[s][i]=inf; 21 dis[s][s]=0; 22 priority_queue<node> q; 23 q.push({s,0}); 24 while(!q.empty()){ 25 node t=q.top(); 26 q.pop(); 27 int o=t.v; 28 if(vis[o]) continue; 29 vis[o]=1; 30 for(int i=0;i<g[o].size();i++){ 31 int to=g[o][i].v; 32 int wo=g[o][i].w; 33 if(dis[s][to]>dis[s][o]+wo){ 34 dis[s][to]=min(dis[s][to],dis[s][o]+wo); 35 q.push({to,dis[s][to]}); 36 } 37 } 38 } 39 return ; 40 } 41 signed main(){ 42 scanf("%lld%lld%lld",&n,&m,&c); 43 int mx=inf; 44 for(int i=1;i<=m;i++){ 45 scanf("%lld%lld%lld",&u[i],&v[i],&p[i]); 46 g[u[i]].pb({v[i],p[i]}); 47 mx=min(mx,p[i]); 48 } 49 if(c<mx){ 50 cout<<"0"; 51 return 0; 52 } 53 for(int i=1;i<=n;i++){ 54 dijkstra(i); 55 } 56 int cur=inf; 57 for(int i=1;i<=n;i++){ 58 for(int j=1;j<=n;j++){ 59 if(i==j) continue; 60 if(dis[i][j]!=inf&&dis[j][i]!=inf){ 61 //cout<<i<<" "<<j<<endl; 62 cur=min(cur,dis[i][j]+dis[j][i]); 63 } 64 } 65 } 66 // cout<<cur<<endl; 67 if(cur!=inf&&c>=cur){ 68 cout<<"2"<<endl; 69 }else{ 70 cout<<"1"<<endl; 71 } 72 return 0; 73 }