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 }
原文地址:https://www.cnblogs.com/pengge666/p/15567002.html