The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online

K
写一下二进制你会发现可以按照首位二进制分类

#include <bits/stdc++.h>
using namespace std;
int a[102000];
int mark[100];
int main(){
	int T;
	ios::sync_with_stdio(0);
	cin>>T;
	while(T--){
		int n;cin>>n;
		memset(mark,0,sizeof(mark));
		int Max=0;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			int cnt=0;
			while(a[i]){
				a[i]/=2;
				++cnt;
			}
			mark[cnt]++;
			Max=max(Max,mark[cnt]);
		}
		printf("%d\n",Max);
	}
	return 0;
}

A
我们可以枚举分段数量 然后用最小的nonperfect去分割看总和是否小于等于n小于就可以加进答案

PPP N PPP N PPP
用两个N即可分成三段

#include <bits/stdc++.h>
using namespace std;
int a[102000];
int mark[100];
int main(){
	int T;
	ios::sync_with_stdio(0);
	cin>>T;

	while(T--){
		int n,m;
		cin>>n>>m;
		int ans1=m;
		int ans2=0;
		for(int i=1;i<=m;i++){
			int t=m%i==0?m/i:m/i+1;
			if(t-1+m<=n){
				ans2=i;
				break;
			}
		}
		cout<<ans1<<" "<<ans2<<endl;
	}
	return 0;
}

C题
模拟
二维数组可以保存状态 显然每个状态会对应到下一个状态 直接循环or 搜索即可 dfs可能爆栈??

#include <bits/stdc++.h>
using namespace std;
struct node{
	string instruct;
	int data;
	int k;
}p[10200];
int n;
bool ok;
bool vis[10005][257];
int main(){
	int T;
	ios::sync_with_stdio(0);
	cin>>T;
	while(T--){
		memset(vis,0,sizeof(vis));
		cin>>n;
		ok=true;
		for(int i=1;i<=n;++i){
			string temp;
			cin>>temp;
			p[i].instruct=temp;
			cin>>p[i].data;
			if(temp[1]!='d'){
				cin>>p[i].k;
			}
		}
		int step=1;
		int now=0;
		while(1){
			if(step==n+1) break;
			if(!ok) break;
			if(vis[step][now]){
				ok=false;
				break;
			}
			else vis[step][now]=true;
			if(p[step].instruct[1]=='d'){
				now=(now+p[step].data)%256;
				step++;
			}
			else if(p[step].instruct[1]=='e'){
				if(now==p[step].data){
					step=p[step].k;
				}
				else{
					step++;
				}
			}
			else if(p[step].instruct[1]=='n'){
				if(now!=p[step].data){
					step=p[step].k;
				}
				else{
					step++;
				}
			}
			else if(p[step].instruct[1]=='l'){
				if(now<p[step].data){
					step=p[step].k;
				}
				else{
					step++;
				}
			}
			else if(p[step].instruct[1]=='g'){
				if(now>p[step].data){
					step=p[step].k;
				}
				else{
					step++;
				}
			}
		}
		if(ok){
			puts("Yes");
		}
		else puts("No");
	}
	return 0;
}

H
写的有点复杂
每次根据上一次状态计算总和
比如
1011010

1235678
235678
13456
1234
234
12
2
观察一下相邻两列的关系推公式
00100
24568
2346
124
24
2

#include <bits/stdc++.h>
using namespace std;
#define ll long long 
ll a[102000];
ll f[102000];
int main(){
	int T;
	ios::sync_with_stdio(0);
	cin>>T;
	while(T--){
		string s;
		cin>>s;
		int len=s.size();
		s='#'+s;
		if(s[1]=='1') a[1]=1;
		else a[1]=2;
		for(int i=2;i<=len;++i){
			if(s[i]==s[i-1]) a[i]=a[i-1]+2;
			else a[i]=a[i-1]+1;
		}
		ll sum=0;
		for(int i=1;i<=len;++i){
			sum+=a[i];
		}
		ll ans=sum;
		ll last=sum;
		for(int i=2;i<=len;++i){
			ll temp=0;
			if(s[i]=='0'){
				if(s[i-1]=='0'){
					temp=last-2*(len-i+1)-(s[i-1]=='0'?2:1);
				}
				else temp=last-1;
			}
			else temp=last-2*(len-i+1)-(s[i-1]=='0'?2:1);
			ans+=temp;
			last=temp;
		}
		cout<<ans<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值