在学校想打一场cf真是不容易.昨晚卡在E离散化的边界处理(也可能是思路错了)那里卡的很久,一直过不去就先睡觉去了.
这场的题目偏易.大多都可暴力乱搞过去.
A. Yet Another Two Integers Problem
题目大意:给两个数,每次可以减去1-10,问最少多少次A==B.
大概就是大数-10接近小数,如果%10的余数 大数大于小数的话,就要增加一次.
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline void read(int &a){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
a = x*f;
}
int solve(int a,int b){
if(a < b) return solve(b,a);
int ans = a/10-b/10;
if(a%10>b%10) ans++;
return ans;
}
int main(){
int t;
cin >> t;
while(t--){
int a,b;
cin >> a >> b;
cout << solve(a,b) << endl;
}
return 0;
}
B. Minimum Product
题目大意:给a,b,x,y,n.a和b可以进行-1操作.这个操作次数不能超过n,而且a不能小于x,b不能小于y.问a×b能达到的最小值.
当时就乱搞了一下,要么先减a,要么先减b.贪心就过去了.毕竟数据范围不允许我们暴力.
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline void read(int &a){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
a = x*f;
}
LL solve(LL a,LL b,LL x,LL y,LL n){
LL num = min(n,b-y);
b -= num;
n -= num;
a -= min(n,a-x);
return a*b;
}
int main(){
int t;
cin >> t;
while(t--){
LL a,b,x,y,n;
cin >> a >> b >> x >> y >> n;
cout << min(solve(a,b,x,y,n),solve(b,a,y,x,n)) << endl;
}
return 0;
}
C. Yet Another Array Restoration
题目大意:给一个n,x,y 构造一个长度为n的等差数列.其中有x和y,要求输出能构造的所有方案中数列中最大值最小的那一个方案.
数据范围很小,暴力枚举公差,x的位置.y的位置就可以了.复杂度n^3.
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline void read(int &a){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
a = x*f;
}
int main(){
int t,n,x,y;
cin >> t;
while(t--){
cin >> n >> x >> y;
int rd,rx,ry,mx=1e9;
fir(d,1,50){
afir(ypos,n,2){
afir(xpos,ypos-1,1){
if((ypos-xpos)*d == y-x && x-d*(xpos-1) > 0){
if((n-ypos)*d+y < mx){
mx = (n-ypos)*d+y;
rd = d;
rx = xpos;
ry = ypos;
}
}
}
}
}
int sta = x-rd*(rx-1);
fir(i,1,n){
cout << sta << " ";
sta += rd;
}
puts("");
}
return 0;
}
D. Decrease the Sum of Digits
题目大意:给一个数,求最少加多少次1能让位数和<s.
每次让最后一个不是0的位数加到0然后每次都检查一下是否<s就可以了.
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline void read(int &a){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
a = x*f;
}
int calc(LL x){
int res = 0;
while(x){
res += x%10;
x/=10;
}
return res;
}
LL pre[20];
int main(){
int t;
cin >> t;
pre[0] = 1;
fir(i,1,18) pre[i] = pre[i-1]*10;
while(t--){
LL n;int s;
cin >> n >> s;
LL ans = 0;
while(calc(n) > s){
LL nn = n;
int ct = 0;
while(nn && !(nn%10)){
ct++;
nn/=10;
}
ans += 1LL*(10-nn%10)*pre[ct];
n += 1LL*(10-nn%10)*pre[ct];
}
cout << ans << endl;
}
return 0;
}
E. Two Platforms
题目大意(如果我没有理解错的话):给n个点的坐标,和两个长度为k的平板.问平板最多能覆盖多少个点(这个平板可以视为长度无限).
我的思路是要么连在一起成为一个k-2k的平板或者分开成两段.
那么就是一个很经典的单调队列问题,分两种情况写就好了.然而昨天调了半个多小时都没有调过去.
WA代码
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#define L 2*i
#define R 2*i+1
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline void read(int &a){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
a = x*f;
}
int x[N],y[N],num[N],tot;
int q[N];
vi all;
int getpos(int x){
return lower_bound(ALL(all),x) - all.begin();
}
int get_pos(int x){
return upper_bound(ALL(all),x) - all.begin();
}
int main(){
int t;
cin >> t;
while(t--){
int n,k;
cin >> n >> k;
all.clear();
mem(num,0);
mem(q,0);
all.pb(0);
fir(i,1,n){
cin >> x[i];
all.pb(x[i]);
}
fir(i,1,n)
cin >> y[i],all.pb(y[i]);
sort(ALL(all));
all.erase(unique(ALL(all)),all.end());
tot = all.size()-1;
fir(i,1,n)
num[getpos(x[i])]++;
int l=1,r=0;
int ans = 1;
fir(i,1,tot){
num[i] += num[i-1];
while(l <= r && all[i] - all[q[l]] >= 2*(k+1)) l++;
if(l <= r) ans = max(ans,num[i]-num[q[l]-1]);
while(l <= r && num[i-1] <= num[q[r]-1]) r--;
q[++r] = i;
}
int mx=0;
fir(i,1,tot){
int kk = get_pos(all[i]-k-1)-1,kkk=0;
if(kk>=1) kkk = get_pos(all[kk]-k-1)-1;
if(kk >= 1){
if(mx < num[kk]-num[max(kkk,0)])
mx = num[kk]-num[max(kkk,0)];
}
ans = max(ans,mx+num[i]-num[max(kk,0)]);
}
cout << ans << endl;
}
return 0;
}