title : Codeforces Round #753 (Div. 3)
date : 2021-11-7
tags : ACM,练习记录
author : Linno
题目链接:https://codeforces.com/contest/1607
做题进度:已补完
给你每个字母的位置,问打完一个字符串要经过的总路程。
直接模拟求出答案即可。
#include
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
int t,ans=0;
mapmp;
string str1,str2;
signed main(){
// ios::sync_with_stdio(0);// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);freopen("out.cpp","w",stout);
cin>>t;
while(t--){
cin>>str1>>str2;
mp.clear();ans=0;
for(int i=0;i
B-Odd Grasshopper
给一个初始位置x和一个轮数n,如果当前位置为奇数则跳右,否则跳左,且第k轮跳k格。问第n轮所在位置。
思路
x只影响第一步的方向,只用看出是从0和1出发并且最后答案加上x就行了。关于跳的方式是一个周期为4的函数,公式见代码。
代码
#include
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
int t,x,n,u,ans;
signed main(){
// ios::sync_with_stdio(0);// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);freopen("out.cpp","w",stout);
cin>>t;
while(t--){
cin>>x>>n;
u=n%4;
if(x&1){
if(u==0){
ans=x;
}else if(u==1){
ans=x+n;
}else if(u==2){
ans=x-1;
}else ans=x-n-1;
}else{
if(u==0){
ans=x;
}else if(u==1){
ans=x-n;
}else if(u==2){
ans=x+1;
}else ans=x+n+1;
}
cout<
C-Minimum Extraction
每轮可在一个序列中删去最小的数且让其他数减去该值,问每轮中最大的序列最小值是多少。
思路
先排序,然后从左往右减即可。类似前缀和的思想。
代码
#include
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
int t,n,ans,sum[N],a[N];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
ans=a[1];
for(int i=2;i<=n;i++){
ans=max(ans,a[i]-a[i-1]);
}
cout<
D-Blue-Red Permutation
给一个序列,每个数有其颜色,蓝色可减,红色可加。问是否能形成一个1~n的排列。
思路
只需要考虑分成红蓝两堆,在排列中让蓝的尽量填大的数,红的尽量填小的数即可。
代码
#include
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
int t,flag,n,a[N];
string str;
signed main(){
// ios::sync_with_stdio(0);// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);freopen("out.cpp","w",stout);
cin>>t;
while(t--){
flag=0;
priority_queue,greater >qg,ql;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cin>>str;
for(int i=1;i<=str.length();i++){
if(str[i-1]=='B') qg.push(a[i]); //这个可以变小,所以是小根堆
else ql.push(a[i]);
}
for(int i=1;i<=n;i++){
if(!qg.empty()&&qg.top()>=i) qg.pop();
else if(!ql.empty()&&ql.top()<=i) ql.pop();
else{
flag=1;
break;
}
}
if(flag) puts("NO");
else puts("YES");
}
return 0;
}
E-Robot on the Board 1
给一个地图和机器人的行走路线,问最远走到哪。
思路
把机器人尽量框在n*m的地图内,如果框不住了,那么最后一格就是要输出的目标。
代码
#include
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
int t,n,m,l,r,u,d,sr,sc,i;
string str;
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);freopen("out.cpp","w",stout);
cin>>t;
while(t--){
cin>>n>>m;
cin>>str;
l=r=u=d=0,sr=sc=0;
for(i=0;im||u-d+1>n) {l++;break;}
if(sc>r) r++;
if(r-l+1>m||u-d+1>n) {r--;break;}
if(sr>u) u++;
if(r-l+1>m||u-d+1>n) {u--;break;}
if(srm||u-d+1>n) {d++;break;}
}
//cout<
F-Robot on the Board 2
随便选一个起点,然后机器人会按照地图上的指示去移动,且每格只能走一次。问从哪里开始走可以走最多的格子。
思路
记忆化搜索,将地图上每一块作为起点的情况考虑进去;成环的情况会比较复杂,但也只需要记住搜索序即可减出答案。
代码
#include
//#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int N=2003;
pairp[N*N],tmp;
int t,n,m,f[N][N],cnt;
bool vis[N][N];
char mp[N][N];
inline int dfs(int x,int y){
p[++cnt]={x,y};
if(vis[x][y]||x<1||x>n||y<1||y>m) return f[x][y];
vis[x][y]=1;
if(mp[x][y]=='U') f[x][y]=dfs(x-1,y)+1;
if(mp[x][y]=='D') f[x][y]=dfs(x+1,y)+1;
if(mp[x][y]=='L') f[x][y]=dfs(x,y-1)+1;
if(mp[x][y]=='R') f[x][y]=dfs(x,y+1)+1;
return f[x][y];
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>t;
while(t--){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>mp[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!vis[i][j]){
cnt=0;
dfs(i,j);
tmp=p[cnt];
for(int k=1;kf[x][y]) x=i,y=j;
cout<
G-Banquet Preparations 1
每道菜有x和y,让他们一共减去m,使得所有菜的x之和与y之和的差值最少。
思路
贪心让一开始x减得更多,y尽量不减,然后计算差值suma-sumb,如果需要继续平衡的话从b-y大的菜开始逐个转移,最终逐渐达到平衡。
代码
#include
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
int t,n,m,ans[N],tmp,t1,t2,a[N],b[N],x[N],y[N];
struct X{
int a,b,x,y,id;
}s[N];
bool cmp1(X u,X v){ //删b啊
if(u.a==v.a) return u.b>t;
for(int T=1;T<=t;T++){
int suma=0,sumb=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>s[i].a>>s[i].b;
suma+=s[i].a;sumb+=s[i].b;
s[i].id=i;s[i].x=0;s[i].y=0;
}
sort(s+1,s+1+n,cmp1);
for(int i=1;i<=n;i++){ //第一次处理先把A全吃了
if(s[i].a>=m) s[i].x=m,s[i].y=m-s[i].x;
else s[i].x=s[i].a,s[i].y=m-s[i].x;
suma-=s[i].x;sumb-=s[i].y; //处理差值
}
sort(s+1,s+1+n,cmp2);
for(int i=1;i<=n;i++){
int tmp=(sumb-suma);
if(tmp<=0){ //现在还是a多于b
break;
}else{ //将删A移到删B
if(tmp<=2*s[i].x){ //差距比较小,可以一次做完
int tt=min(tmp/2,s[i].b-s[i].y); //转移量
s[i].x-=tt;s[i].y+=tt;
suma+=tt;sumb-=tt;
}else{ //全转吃b吧
int tt=min(s[i].x,s[i].b-s[i].y); //最多能转多少?
s[i].y+=tt;
sumb-=tt;
suma+=tt;
s[i].x-=tt;
}
}
}
sort(s+1,s+1+n,cmp3);
cout<
H-Banquet Preparations 2
每道菜xi,yi可以减去总和为mi的价值,问最终相同的菜最多的情况。
思路
考虑如果最终两道菜相同,那么x+y-m一定是相同的。那么我们按每个t=x+y-m分组,并且按x从小到大进行排序,每道菜的x都要减到min(mina,t)的位置,如果不能减到,就说明是不同的菜。
代码
#include
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e6+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
int t,n,ans,need[N],mx,mi;
struct X{
int a,b,m,x,y,id;
}s[N];
vectorvt[N];
bool cmp(X aa,X bb){return aa.a>t;
for(int T=1;T<=t;T++){
cin>>n;
ans=0;
for(int i=1;i<=n;i++){
cin>>s[i].a>>s[i].b>>s[i].m;
s[i].x=s[i].y=0;
s[i].id=i;
need[i]=s[i].a+s[i].b-s[i].m;
vt[need[i]].push_back(s[i]);
}
for(int i=1;i<=n;i++){
if(vt[need[i]].size()){
sort(vt[need[i]].begin(),vt[need[i]].end(),cmp);
for(int j=0,mi=-1e9;j
你可能感兴趣的:(ACM,练习记录,杂项,acm竞赛,程序设计,c++,贪心算法)