2021ccpc网络选拔赛

1.Cut The Wire

考察:思维题

思路:奇偶数分开计算
(1)满足条件的偶数部分:因为x对应x/2,所以x/2之前的数都不行,所以a=n-n/2;
(2)满足条件的奇数部分:设b=(n-1)/3+1,如果b是奇数,那么b=(n-b)/2+1;如果b是偶数,那么b=(n-b+1)/2。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve(){
	ll n,a,b,ans;
	cin>>n;
	a=n-n/2;//偶数部分
	//奇数部分
	b=(n-1)/3+1;
	if(b%2) b=(n-b)/2+1;//如果b是奇数 
	else b=(n-b+1)/2;//b是偶数 
	ans=a+b;
	cout<<ans<<endl; 
}

int main(){
	int t;
	cin>>t; 
	while(t--){
		solve();
	}
	return 0;
}

2.Command Sequence

题意
求U的个数 == D的个数&&L的个数 == R的个数的子串数目

考察:前缀和

思路
设置一个前缀和sum[N]数组 ,U:+1e5,D:-1e5, L:+1,R:-1。

要满足条件,则这段子串的序列和为0,即sum[r]-sum[l-1]==0,等价于找sum[i]出现的次数。

(1)当sum[i]==0时,表明从位置1-i的子串满足条件,ans++
(2)当到位置i时,如果sum[i]已经出现过x次,那么可与之前的sum[i]配对x次,ans+=x;
sum[i]出现次数++。 那么遍历到最后,ans的累计值就是答案

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
ll sum[N];
void solve(){
	unordered_map <ll,ll> mp;//记录前缀和出现的次数
	int n;
	scanf("%d",&n);
	memset(sum,0,sizeof(sum));//每次记得清0啊
	char s[N];
	scanf("%s",s+1);
	ll ans=0;
	for(int i=1;i<=n;i++){
		if(s[i]=='U') sum[i]=sum[i-1]+1e5;
		if(s[i]=='D') sum[i]=sum[i-1]-1e5;
		if(s[i]=='L') sum[i]=sum[i-1]+1;
		if(s[i]=='R') sum[i]=sum[i-1]-1;
		if(sum[i]==0) ans++;
		if(mp[sum[i]]) ans+=mp[sum[i]];
		mp[sum[i]]++;
	}
    
	cout<<ans<<endl;
}

int main(){
	int t;
	cin>>t; 
	while(t--){
		solve();
	}
	return 0;
}

3.Power Sum

考察:构造

思路
因为(x+1)^2 - (x+2)^2 - (x+3)^2 +(x+4)^2 = 4,所以凑4,再凑模4后的余数。
4:1001
余数及对应的序列为
1:1
2:0001
3:01

代码如下:

#include <bits/stdc++.h>
using namespace std;

void solve(){
	int n;
	cin>>n;
	if(n%4==0) cout<<n<<endl;//只有1001,不多不少,就是n 
	if(n%4==1) cout<<n<<endl,cout<<"1",n-=1;//剩下1,刚好1的长度为1,所以为n 
	if(n%4==2) cout<<n+2<<endl,cout<<"0001",n-=2;//剩下2,而0001的长度为4,所以为n+2 
	if(n%4==3) cout<<n-1<<endl,cout<<"01",n-=3;//剩下3,而01得长度为1,所以为n-1 
	for(int i=1;i<=n/4;i++){
		cout<<"1001";
	}
	cout<<endl;
}

int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

4.Time-division Multiplexing

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值