A.Vasya and Socks
题意:有n个袜子,每天穿一双晚上扔掉,每m天再买一双。求一共能连续穿多少天?
题解:给n分成 n/m*m和n-n/m*m两部分递归计算。
B.Little Dima and Equation
题意:x = b·s(x)a + c,s(x)是x的各位数字和。输入a、b、c,求使等式成立的X。
题解:枚举每个S(x),求对应的x。x的范围是0-81,不到为什么他们hack了好多72的。
C.Present
题意:有n盆花,每盆花的高度为a[i]。每天可以选一段连续的的序号的花浇灌,浇灌的花高度+1。连续浇m天,求最矮的花的高度。
题解:二分答案 + check()。用mi记录当前位置前面影响当前位置的浇灌次数,队列q记录影响的位置序列。当前位置需要高度大于mi,则当前位置需要浇灌mi-x天,mi+=x。若队首的与当前位置的距离大于w,则减去队首的浇灌次数。
代码:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #include <string> using namespace std; #define For(i,a) for(i=0;i<a;i++) #define Foru(i,a,b) for(i=a;i<=b;i++) #define Ford(i,a,b) for(i=a;i>=b;i--) #define clr(ar,vel) memset(ar,vel,sizeof(ar)) #define PB push_back typedef long long ll; const int maxint = 0x7fffffff; const ll maxll = 1LL<<60; int a[100010]; int b[100010]; int n, m, w; queue<int> q; int check(ll x){ // cout << x << endl; // cout << "###################" << endl; ll mi = 0; int cnt = 0, fn; while(q.size()) q.pop(); for(int i = 0; i < n; i ++) b[i] = x-a[i]; for(int i = 0; i < n; i ++){ if( q.size()) { fn = q.front(); if( i - fn >= w ) { mi -= b[fn]; q.pop(); } } // cout << mi << ' ' << b[i] << ' ' << i << ' ' << fn << endl; if( b[i] - mi > 0) { int t = b[i] - mi; mi += b[i]-mi; b[i] = t; q.push(i); cnt += b[i]; } if( cnt > m ) return 0; } // cout << x << ' ' << cnt << endl; return cnt <= m; } int main(){ ll sum; while(~scanf("%d%d%d",&n,&m,&w)){ sum = 0; for(int i = 0; i < n; i ++) { scanf("%d",a+i); sum += a[i]; } ll l, r, mid; l = 1; r = 2000000000; while( l < r){ mid = (l+r)/2; if( check(mid)){ // cout << "mid " << mid << endl; l = mid+1; } else r = mid; } printf("%d\n",l-1); } return 0; }
D.Little Victor and Set
题意:输入l、r、k,求一个集合set,使得1 <= set.size <= k,队列元素连续异或的结果最小。
题解:1、k=1时,l最小。2、k=2时,i^(i+1)=1、3、5……,求最小值。3、k >= 4时,连续四个异或是0。
4、 k=3时,当时没想明白,看题解也看了半天才弄懂。i%2 == 0时,i^(i+1) == 1。若结果等于0,则三个数异或等于0。
1:3个数 l<=x<=y<=z<=r,因为x^y^z == 0,z的二进制最高位为1,则y的最高位为1,x的最高为等于0. 2:若x的第二位为0,因为异或结果为0,则x,y的第二位同时为0或1.x、y、z更接近所以x,y的第二位为0。重复1. 3:若x的第二位为1,因为异或结果为零,y<z,所以y的第二位为0,z的第二位为1. 即: x: 011……1 1 -> mn <<= 1, mn++; y: 101……1 2 -> mx <<= 1, mx-1; z: 110……0 3 -> mx ;
代码:
<span style="font-size:12px;">#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #include <string> using namespace std; #define For(i,a) for(i=0;i<a;i++) #define Foru(i,a,b) for(i=a;i<=b;i++) #define Ford(i,a,b) for(i=a;i>=b;i--) #define clr(ar,vel) memset(ar,vel,sizeof(ar)) #define PB push_back typedef long long ll; const int maxint = 0x7fffffff; const ll maxll = 1LL<<60; int check3(ll l, ll r, ll k){ ll mn = 1; ll mx = 3; while( mx <= r){ if( mn >= l){ cout << 0 << endl; cout << 3 << endl; cout << mn << ' ' << mx-1 << ' ' << mx << endl; return 0; } mn <<= 1; mx <<= 1; mn ++; } if( k >= 4) for(ll i = l+3; i <= r; i ++){ if( (i^(i-1)^(i-2)^(i-3)) == 0){ cout << 0 << endl; cout << 4 << endl; cout << i << ' ' << i-1 << ' ' << i-2 << ' ' << i-3 << endl; return 0; } } ll mi = l; for(ll i = l+1; i <= r; i ++){ if( (i^(i-1)) == 1) { cout << 1 << endl; cout << 2 << endl; cout << i << ' ' << i-1 << endl; return 0; } if( (i^(i-1)) <= mi) mi = i^(i-1); } for(ll i = l+1; i <= r; i ++){ if( (i^(i-1)) == mi) { cout << mi << endl; cout << 2 << endl; cout << i << ' ' << i-1 << endl; return 0; } } cout << l << endl; cout << 1 << endl; cout << l << endl; return 0; } int main(){ ll n, m, k; int flag; while(cin >> n >> m >> k){ flag = 0; if(k == 1 || m-n == 0) { cout << n << endl; cout << 1 << endl; cout << n << endl; } else if( k == 2 || m-n == 1){ ll mi = n; for(ll i = n+1; i <= m; i ++){ if( (i^(i-1)) == 1) { cout << 1 << endl; cout << 2 << endl; cout << i << ' ' << i-1 << endl; flag = 1; break; } if( (i^(i-1)) <= mi) mi = i^(i-1); } if( !flag ) for(ll i = n+1; i <= m; i ++){ if( (i^(i-1)) == mi) { cout << mi << endl; cout << 2 << endl; cout << i << ' ' << i-1 << endl; flag = 1; break; } } if( !flag ) { cout << n << endl; cout << 1 << endl; cout << n << endl; } } else if( k >= 3 || m-n >= 2) { check3(n, m, k); } } return 0; }</span>
E.Roland and Rose
题意:
题解: