【Codeforces Round #719 (Div. 3)】Codeforces-1520ABCDEF1G

A. Do Not Be Distracted!

读了十分钟才看懂题意我菜死了QAQ
查询是否出现相同字母的连续区间即可

string s;
map<char,int>mp;
void solves(){
	int n;cin>>n;
	cin>>s;
	mp.clear();
	for(int i=0;i<n;++i){
		if(!mp[s[i]]){
			mp[s[i]]=1;
			int j=i;
			while(s[i]==s[j]) ++j;
			if(j==n)break;
			i=j-1;
		} else{
			cout<<"NO\n";return ;
		}
	}
	cout<<"YES\n";
}

B. Ordinary Numbers

位 数 1 1 2 3 . . . 8 9 2 11 22 33 . . . 88 99 3 111 222 333 . . . 888 999 . . . . . . . . . . . . . . . . . . . . . 8 11111111 22222222 33333333 . . . 88888888 99999999 9 111111111 222222222 333333333 . . . 888888888 999999999 \begin{array}{c|ccc} 位数 & \text{} & \text{} & \text{} \\ \hline 1 & 1 & 2 & 3 & ... & 8 & 9\\ 2 & 11 & 22 & 33 & ... & 88 & 99\\ 3 & 111 & 222 & 333 & ... & 888 & 999\\ ... & ... & ... & ...&...&...&...\\ 8 & 11111111 & 22222222 & 33333333 &...&88888888&99999999\\ 9 & 111111111 & 222222222 & 333333333 &...&888888888&999999999\\ \end{array} 123...89111111...11111111111111111222222...22222222222222222333333...33333333333333333..................888888...88888888888888888999999...99999999999999999

显然十进制n位数必有(n-1)*9个ordinary numbers,然后再与其同位数的111…,222…,…,999…比较。

void solves(){
	ll n;cin>>n;
	int cnt=0;
	int m=n;
	while(n){
		++cnt;
		n/=10;
	}
	int ans=(cnt-1)*9;
	ll re=1;
	for(int i=1;i<cnt;++i) re=re*10+1;
	for(ll i=1;i<=10;++i){
		if(re*i>m){
			ans+=(i-1);
			break;
		}
	}
	cout<<ans<<endl;
}

C. Not Adjacent Matrix

沿着间隔的对角线填充必能使各数不相邻。但n=2时必有任一对角线都互相相邻。
说的有点抽象,举个栗子:
先从左下角依次沿间隔的对角线填充到右上角
5 10 13 6 11 2 7 12 3 8 1 4 9 \begin{array}{c|c|c|c|c} 5 & &10 & &13 \\ \hline & 6 & & 11 &\\ \hline 2 & & 7 & &12 \\ \hline & 3& & 8 &\\ \hline 1 & &4& &9\\ \end{array} 52163107411813129
再倒回左下角第二条对角线按顺序沿间隔的对角线填充到右上角
5 20 10 24 13 16 6 21 11 25 2 17 7 22 12 14 3 18 8 23 1 15 4 19 9 \begin{array}{c|c|c|c|c} 5 & 20 &10 &24 &13 \\ \hline 16 & 6 & 21 & 11 &25\\ \hline 2 &17 & 7 & 22&12 \\ \hline 14& 3& 18 & 8 &23\\ \hline 1 & 15 &4& 19&9\\ \end{array} 51621412061731510217184241122819132512239

void dfs(int x,int y){
	if(x==n+1||y==n+1)return ;
	mp[x][y]=++tot;
	return dfs(x+1,y+1);
}
void solves(){
	cin>>n;
	tot=0;
	if(n==2){
		cout<<-1<<endl;return ;
	}
	for(int i=n;i>0;i-=2) dfs(i,1);
	for(int i=3;i<=n;i+=2) dfs(1,i);
	for(int i=n-1;i>0;i-=2) dfs(i,1);
	for(int i=2;i<=n;i+=2) dfs(1,i);
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j)cout<<mp[i][j]<<" ";cout<<endl;
	}
}

D. Same Differences

我真的好傻,最后半小时才想到正解,而且貌似还因为爆int wa了一次QAQ
要使得 a j − a i = j − i a_j-a_i=j-i ajai=ji,则有 a j − j = a i − i a_j-j=a_i-i ajj=aii。剩下的就是初中数学知识了。

const int N=2e5+7;
int a[N];
map<ll,ll>cnt;
void solves(){
	int n;cin>>n;
	cnt.clear();
	ll ans=0;
	for(ll i=1;i<=n;++i){
		cin>>a[i];
		++cnt[a[i]-i];
	}
	for(ll i=-n;i<=n;++i){
		ans+=(cnt[i]-1)*cnt[i]/2;//这一步可能爆int(?)
	}
	cout<<ans<<endl;
}

E. Arranging The Sheep

这个题的思想和很久很久之前的一场div2的b题(为了找这个b题我翻了好久QAQ)是一样的,向中位数靠拢即可。只不过一个是二维的曼哈顿距离,一个是一维的。有点可惜,昨晚没时间读这题了QAQ。
ps有人问我怎么证明中位数,看到隔壁一个博主证挺好的,我就不证了。

string s;
void solves(){
	int n;cin>>n>>s;
	vector<int>sum;
	int cnt=0;
	for(int i=0;i<n;++i){
		if(s[i]=='*'){
			++cnt;
			sum.push_back(i);
		}
	}
	int mid=0;
	if(sum.size()) mid=sum[cnt/2];
	ll ans=0;
	for(int i=0;i<sum.size();++i){
		ans+=abs(sum[i]-( mid-(cnt/2-i) ));
	}
	cout<<ans<<endl;
}

F1. Guess the K-th Zero (Easy version)

一眼二分。n在2e5范围且只能查询20次,那就需要logn的解法,二分的复杂度也是刚好符合的。

void ask(int l,int r,int k){
	if(l==r){
		cout<<"! "<<l<<endl;
	} else{
		int m=(l+r)>>1;
		cout<<"? "<<l<<" "<<m<<endl;
		int val;cin>>val;
		if(m-l+1-val<k){
			ask(m+1,r,k+val-m+l-1);
		} else{
			ask(l,m,k);
		}
	}
}
void solves(){
	int n,t,k;cin>>n>>t>>k;
	ask(1,n,k);
}

F2. Guess the K-th Zero (Hard version)

看心情填坑

G. To Go Or Not To Go?

听说是sb题,但我感觉我是sb。
要么只传送一次,要么不传送。像样例那样中间截断的话跑两次bfs就好了。取两种情况的最小值就行了。还是要注意一下细节吧,我细节处理的不好wa了好几次。

#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
const int N=2e3+7;
const int mod=1e9+7;
using namespace std;
ll mp[N][N],a[N][N],b[N][N];
int dir[4][2]{{1,0},{-1,0},{0,1},{0,-1}};
ll n,m,w;
ll INF=(1ll<<60);//初始化inf尽可能大一点
void bfs(int x,int y,ll cost[][N]){
	queue<pair<int,int>>q;
	pair<int,int>step;
	q.push({x,y});
	int nx,ny;
	while(q.size()){
		step=q.front();
		q.pop();
		for(int i=0;i<4;++i){
			nx=step.first+dir[i][1];
			ny=step.second+dir[i][0];
			if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mp[nx][ny]!=-1&&cost[nx][ny]==-1){
				cost[nx][ny]=cost[step.first][step.second]+1;
				q.push({nx,ny});
			}
		}
	}
}
void solves(){
	cin>>n>>m>>w;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j)cin>>mp[i][j];
	}
	memset(a,-1,sizeof(a));
	memset(b,-1,sizeof(b));
	a[1][1]=b[n][m]=0;
	bfs(1,1,a);
	bfs(n,m,b);
	ll ans1=INF,ans2=INF,ans=INF;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			if(mp[i][j]>0&&a[i][j]>=0){
				ans1=min(ans1,a[i][j]*w+mp[i][j]);
			}
		}
	}
	for(int i=n;i>0;--i){
		for(int j=n;j>0;--j){
			if(mp[i][j]>0&&b[i][j]>=0){
				ans2=min(ans2,b[i][j]*w+mp[i][j]);
			}
		}
	}
	if(a[n][m]==b[1][1]&&b[1][1]>0){
		ans=min(a[n][m]*w,ans2+ans1);
	} else{
		ans=ans2+ans1;
	}
	cout<<(ans>=INF ? -1:ans)<<endl;
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int OwO=1;
//	cin>>OwO;
	while(OwO--){
		solves();
	}
}
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值