题意:有n个袜子,每天穿一双晚上扔掉,每m天再买一双。求一共能连续穿多少天?
题解:给n分成 n/m*m和n-n/m*m两部分递归计算。
题意: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;
}
题意:输入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>
题意:
题解: