Codeforces Round #686 Div. 3

A. Special Permutation

题目要求构造一个数列,保证 a[i] != i
直接将1-n的数列向后移一位即可

int T,n;
int a[maxn];
 
int main(){
	
	scanf("%d",&T);
	while(T--){
		
		memset(a,-1,sizeof a);
		scanf("%d",&n);
		for(int i=1;i<n;i++){
			a[i] = i+1;
		}
		a[n] = 1;
		for(int i=1;i<n;i++){
			printf("%d ",a[i]);
		}
		printf("%d\n",a[n]);
	}
	return 0;
}

B. Unique Bid Auction

题目要求输出最小并且只有一个的数字,不存在输出-1
定义一个数组用来记录每个数字出现的次数
然后遍历找到出现一次的数字
再遍历一遍找到这个数字对应原数组下标即可

int T,n;
int a[maxn],b[maxn];
 
int main(){
	
	scanf("%d",&T);
	while(T--){
		
		int ans = -1;
		int id = -1;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) b[i] = 0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			b[a[i]]++; // 记录每个数字的种数 找到只有一种的那个数 
		}
		
		for(int i=1;i<=n;i++){
			if(b[i] == 1){
				id = i; // 记录下只有一种并且最小的数字 
				break; 
			}
		}
		for(int i=1;i<=n;i++){
			if(a[i] == id){
				ans = i;
				break;
			} 
		}
		printf("%d\n",ans);
	}
	return 0;
}

C. Sequence Transformation

题目要求给定一个序列,选一个固定的数字
每次选取不包含这个数的区间删去
最后保证序列中剩余的全部都是一开始选定的数字
问最少的操作次数

我们可以把序列分成好几段,去记录相同数字的段数
例如序列 1 2 3 2 2 2 1
数字1的段数就是2 数字2的段数是2 数字3的段数是1
这样我们就可以发现如果选定数字是1
操作次数就是数字1的段数-1
如果选定数字是2
操作次数就是数字2的段数+1
如果将序列改成1 2 3 2 2 2 3
那么如果选定数字是3
操作次数就是数字3的段数
总结一下
选定数字1时序列的头尾元素都是1
如果是这样一个序列1 2 3 1 2 1 ,操作次数依旧是数字1的段数-1,所以如果首尾元素相同并且是选定数字的话,操作次数就是选定数字的段数-1
选定数字2时序列头尾元素都不是选定元素
那么此时操作次数就是选定数字的段数+1
选定数字3时序列首尾元素中有一个与选定数字相同
此时的操作次数就是选定数字的段数

int T,n;
int a[maxn],b[maxn],cnt[maxn];

int main(){
	
	scanf("%d",&T);
	while(T--){
		
		int ans = INF;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) cnt[i] = 0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		
		for(int i=1;i<=n;i++){ // 求每个数的连续块数 
			cnt[a[i]]++;
			while(i+1 <= n && a[i] == a[i+1]) i++;
		}
		
		int tmp = 0;
		for(int i=1;i<=n;i++){
			if(cnt[a[i]] != 0){
				if(a[1] == a[n] && a[1] == a[i]){
					tmp = cnt[a[i]] - 1;
				}else if(a[1] == a[i] || a[n] == a[i]){
					tmp = cnt[a[i]];
				}else if(a[1] != a[i] && a[n] != a[i]){
					tmp = cnt[a[i]] + 1;
				}
			}
			ans = min(ans,tmp);
		}
		printf("%d\n",ans);
	}
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你数过天上的星星吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值