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题待补。