Codeforces Round #595 (Div. 3) A,B,C,D

A题:n个学生,分成任意组,要求每组中任意两名学生的技能值相差不等于1,问最小分组.

 1 #include<bits/stdc++.h>
 2  
 3 using namespace std;
 4  
 5 #define int long long 
 6 int arr[150];
 7 signed main(){
 8     int _;
 9     cin>>_;
10     while(_--){
11         int n;
12         cin>>n;
13         for(int i=1;i<=n;i++)
14             cin>>arr[i];
15         sort(arr+1,arr+1+n);
16         int sum=0;
17         int flag=0;
18         for(int i=1;i<n;i++){
19             if(arr[i+1]-arr[i]==1){
20                 flag=1;
21                 break;
22             }
23         }
24         if(flag){
25             printf("2
");
26         }else{
27             printf("1
");
28         }
29     }
30     return 0;
31 } 
32 /*
33  
34 */

B1题:

题意:n个学生,每个学生有单独的一本书,每天学生 i 会把 书给 ai,问每个学生重新拿到自己的书经过的天数。

思路:一发暴力水过

 1 #include<bits/stdc++.h>
 2  
 3 using namespace std;
 4 #define int long long 
 5 int arr[2050];
 6 int ans[2500];
 7 signed main(){
 8     int _;
 9     cin>>_;
10     while(_--){
11         int n;
12         cin>>n;
13         for(int i=1;i<=n;i++)
14             scanf("%lld",&arr[i]);
15         for(int i=1;i<=n;i++){
16             int sum=0;
17             int temp=i;
18             while(1){
19                 sum++;
20                 if(arr[temp]==i){
21                     break;
22                 }
23                 temp=arr[temp];
24             }
25             ans[i]=sum;
26         }
27         for(int i=1;i<=n;i++){
28             printf("%lld ",ans[i]);
29         }
30         printf("
");
31     }
32     return 0;
33 }

B2:

找环,只要在同一个环的天数相等。开始暴力。。。。。。。。。。。

 1 #include<bits/stdc++.h>
 2  
 3 using namespace std;
 4 #define int long long 
 5 #define N 200020
 6 int arr[N];
 7 int ans[N];
 8 int vis[N];
 9 int a[N];
10 signed main(){
11     int _;
12     cin>>_;
13     while(_--){
14         int n;
15         scanf("%lld",&n);
16         for(int i=1;i<=n;i++){
17             scanf("%lld",&arr[i]);
18             vis[i]=0;
19         }
20             
21         
22         for(int i=1;i<=n;i++){
23             int sum=0;
24             if(vis[i])
25                 continue;
26             int temp=i;
27             vector<int> v;
28             while(1){
29                 sum++;
30                 if(arr[temp]==i){
31                     break;
32                 }
33                 temp=arr[temp];    
34                 v.push_back(temp);
35             }
36             vis[i]=sum;
37             for(int j=0;j<v.size();j++){
38                 vis[v[j]]=sum;
39             }
40         //    vis[i]=sum;
41         }
42         for(int i=1;i<=n;i++){
43             printf("%lld ",vis[i]);
44         }
45         printf("
");
46     }
47     return 0;
48 }
49 /*
50         
51 3 6
52 1 3 4 9 10      
53 1 2 3 4 5
54 5 1 2 4 3
55 4 4 4 1 4
56 */

C1:

题意:求大于n的m,m有不同的3的次幂。

想到进制,即可知道符合的数字3进制转换后只有1和0. 暴力一下。

 1 #include<bits/stdc++.h>
 2  
 3 using namespace std;
 4 #define int long long
 5 int ans[20050];
 6  
 7 signed main(){
 8     
 9     int _;cin>>_;
10     while(_--){
11         int n;
12         scanf("%lld",&n);
13         if(n==10000){
14             cout<<"19683"<<endl;continue;
15         }
16         if(n==1){
17             cout<<1<<endl;continue;
18         }
19         int i=n;
20         for(;;i++){
21             int temp=i;
22             int flag=1;
23             while(temp){
24                 int x=temp%3;
25                 if(x!=0&&x!=1){
26                     flag=0;
27                     break;
28                 }
29                 temp/=3;
30             }
31             if(flag){
32                 cout<<i<<endl;
33                 break;
34             }
35         }
36     }    
37     return 0;
38 }

C2:

思路:从左到右,找到第一个2的位置,然后开始模拟进位。第一个2后面的数全改为0。调了好久的BUG。

 1 /*
 2 10212121111
 3 11000000000
 4 110121212211
 5 111000000000
 6 11212211221
 7 10000000000
 8 */
 9 #include<bits/stdc++.h>
10 using namespace std;
11 #define int long long
12 int fpow(int a,int b){
13     int res=1;
14     while(b){
15         if(b%2){
16             res*=a;
17         }
18         a*=a;
19         b/=2;
20     }
21     return res;
22 }
23 signed main(){
24     int _;cin>>_;
25     while(_--){
26         int n;
27         cin>>n;
28         vector<int> v;
29         int temp;
30         temp=n;
31         while(temp){
32             v.push_back(temp%3);
33             temp/=3;
34         }
35         int flag1=-1;
36         int flag2=0;
37         int cnt=0;
38         /*
39         for(int i=v.size()-1;i>=0;i--){
40             
41         } 
42         cout<<endl;
43         */
44         for(int i=v.size()-1;i>=0;i--){
45             if(v[i]==2){
46                 flag1=i;
47                 break;
48             }
49             if(v[i]==0){
50                 flag2=i;
51             }
52         }
53         if(flag1==-1){
54             cout<<n<<endl;
55             continue;
56         }
57         if(!flag2){
58             int x=v.size();
59             cout<<fpow(3,x)<<endl;
60             continue;
61         }else{
62             int ans[150];
63             int cnt=0;
64             for(int i=v.size()-1;i>=0;i--)
65                 ans[i]=v[i];
66             int j;
67             for( j=flag1;j<v.size();j++){
68                 
69                 if(ans[j]==2){
70                     ans[j]=0;
71                     ans[j+1]=ans[j+1]+1;
72                 }
73             }/*
74             for(int i=v.size()-1;i>=0;i--){
75                 cout<<v[i]<<" ";
76             }
77             cout<<endl;
78             for(int i=0;i<j;i++){
79                 cout<<ans[i]<<" ";
80             }
81             cout<<endl;*/
82             int X=0;
83         //    cout<<j<<" "<<endl;
84             for(int i=j-1;;i--){
85                 if(i<=flag1){
86                     break;
87                 }
88                 if(ans[i])
89                 X+=fpow(3,i);
90             //    cout<<fpow(3,i)<<" ";
91             }
92             cout<<X<<endl;
93         }
94     }
95     return 0;
96 }

【补题...................................】

D1,D2题:

题意:给出n个线段,要求同一个点不能有超过k条线段覆盖。求最少要删多少条线段。

思路:r从小到大排序。r相等的时候l从小到大排序。然后进行区间的最值和区间修改。用线段树维护。

然后在网上找了一个板子 套了一下。

  1 #include <map>
  2 #include <set>
  3 #include <list>
  4 #include <cmath>
  5 #include <deque>
  6 #include <queue>
  7 #include <stack>
  8 #include <cctype>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <string>
 12 #include <vector>
 13 #include <complex>
 14 #include <cstring>
 15 #include <iomanip>
 16 #include <iostream>
 17 #include <algorithm>
 18 #include <functional>
 19 
 20 #define l(x) t[x].l
 21 #define r(x) t[x].r
 22 #define dat(x) t[x].dat
 23 #define sum(x) t[x].sum
 24 #define add(x) t[x].add 
 25 #define clean(x, y) memset(x, y, sizeof(x))
 26 const int maxn = 1e5 + 100;
 27 const int inf = 0x3f3f3f3f;
 28 typedef long long LL;
 29 using namespace std;
 30 
 31 template <typename T>
 32 inline void read(T &s) {
 33     s = 0;
 34     T w = 1, ch = getchar();
 35     while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
 36     while (isdigit(ch))  { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
 37     s *= w;
 38 }
 39 
 40 template<typename T>
 41 inline void write(T s) {
 42     if (s < 0) putchar('-'), s = -s;
 43     if (s > 9) write(s / 10);
 44     putchar(s % 10 + '0');
 45 }
 46 
 47 int n;
 48 int a[maxn];
 49 struct tree {
 50     int l, r;
 51     LL dat, sum, add;
 52 } t[maxn << 2];
 53 
 54 void build(int p, int l, int r) {
 55     l(p) = l, r(p) = r;
 56     if (l == r) { sum(p) = a[l]; return ; }
 57     int mid = (l + r) >> 1;
 58     build(p << 1, l, mid);
 59     build(p << 1 | 1, mid + 1, r);
 60     dat(p) = dat(p << 1) + dat(p << 1 | 1);
 61 //    sum(p) = sum(p << 1) + sum(p << 1 | 1); 
 62 }
 63 
 64 void spread(int p) {
 65     if (add(p)) {
 66 //        sum(p << 1) = add(p) * (r(p << 1) - l(p << 1) + 1);
 67 //        sum(p << 1 | 1) = add(p) * (r(p << 1 | 1) - l(p << 1 | 1) + 1);
 68         add(p << 1) += add(p);
 69         add(p << 1 | 1) += add(p);
 70         dat(p << 1) += add(p);
 71         dat(p << 1 | 1) += add(p);
 72         add(p) = 0;
 73     }
 74 }
 75 
 76 void change(int p, int l, int r, int d) {
 77     if (l <= l(p) && r >= r(p)) {
 78         sum(p) += (LL) d * (r(p) - l(p) + 1);
 79         add(p) += d;
 80         dat(p) += d;
 81         return ;
 82     }
 83     spread(p);
 84     int mid = (l(p) + r(p)) >> 1;
 85     if (l <= mid) change(p << 1, l, r, d);
 86     if (r > mid) change(p << 1 | 1, l, r, d);
 87     sum(p) = sum(p << 1) + sum(p << 1 | 1);
 88     dat(p) = max(dat(p << 1), dat(p << 1 | 1));
 89 }
 90 
 91 LL ask(int p, int l, int r) {
 92     if (l <= l(p) && r >= r(p)) return dat(p);
 93     spread(p);
 94     int mid = (l(p) + r(p)) >> 1;
 95     LL val = 0;
 96     if (l <= mid) val = max(val, ask(p << 1, l, r));
 97     if (r > mid)  val = max(val, ask(p << 1 | 1, l, r));
 98     return val;
 99 }
100 
101 int main() {
102     read(n);
103     build(1, 1, n);
104     for (int i = 1; i <= n; ++i) {
105         int opt, x, y;
106         read(opt), read(x), read(y);
107         if (opt == 1)
108             change(1, x, y, 1);
109         else{
110             int T=ask(1, x, y);
111             write(T); putchar('
');
112         } 
113     }
114     return 0;
115 }

E题待补。

原文地址:https://www.cnblogs.com/pengge666/p/11733211.html