codeforces 834 Div3 整个题解

A Yes-Yes 

首先构建出来YesYes序列

然后n²枚举l与r 再\Theta (N^{^{^{^{3}}}})可以比较快速写

#include <bits/stdc++.h>
using namespace std;
#define int long long
char s[1010];
char c[1010];
void solve()
{
cin>>(s+1);
int l=strlen(s+1);
int sign=0;
for(int i=1;i<=100;i++)
for(int j=i;j<=100;j++){
	if(j-i+1!=l)continue;
	int val=0;int cnt=1;
	for(int k=i;k<=j;k++){
		if(c[k]!=s[cnt]){
			val=1;
		}
		cnt++;
	}
	if(!val)sign=1;
}
if(sign)printf("YES\n");
else printf("NO\n");
for(int i=1;i<=l;i++)s[i]=0;
}
signed main()
{
for(int i=1;i<=1000;i+=3){
	c[i]='Y';c[i+1]='e';c[i+2]='s';
}
int T;
cin>>T;
while(T--){
	solve();
}	
}

B Lost Permutation

直接暴力枚举缺少的部分,再往最大值往上暴力延申即可

#include <bits/stdc++.h>
using namespace std;
#define int long long
int m,s;int b[101];
int sum=0;
int vis[1010];
void solve()
{
cin>>m>>s;sum=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=m;i++){cin>>b[i];vis[b[i]]=1;}
int mx=*max_element(b+1,b+1+m);
for(int i=1;i<=mx;i++){
	if(!vis[i]){
		sum+=i;
	}
}
if(sum>s){
	printf("no\n");
	return ;
}
if(sum==s){
	printf("yes\n");
	return ;
}
for(int i=mx+1;i<=1000;i++){
	if(sum>=s)break;
	sum+=i;
}
if(sum==s)
	printf("YES\n");
	else printf("no\n");

}
signed main()
{
int T;
cin>>T;
while(T--){
	solve();
}	
}

C Thermostat

答案只有0 1 2 3 -1四种

0略 1直接暴力判断 2考虑题目约束条件|a2-a1|>=x发现到两边l,r一定最优

-1主要判断到不了的情况 3不用判了,补集转换

#include <bits/stdc++.h>
using namespace std;
#define int long long
int st,ed,l,r,x;
void solve()
{
cin>>l>>r>>x;
cin>>st>>ed;
if(st==ed){
	printf("0\n");
	return ;
}
if(ed>r||ed<l){
	printf("-1\n");
	return ;
}
if(abs(ed-st)>=x){
	printf("1\n");
	return ;
}
if(abs(st-l)>=x&&abs(ed-l)>=x){
		printf("2\n");
		return ;
}
if(abs(st-r)>=x&&abs(ed-r)>=x){
		printf("2\n");
		return ;
}
if(abs(st-l)<x&&abs(st-r)<x){
	printf("-1\n");
	return ;
}
if(abs(ed-l)<x&&abs(ed-r)<x){
	printf("-1\n");
	return ;
}
printf("3\n");
}
signed main()
{
int T;
cin>>T;
while(T--){
	solve();
}	
}

D  Make It Round

经典把2与5拆开

对n这样做,然后考虑慢慢添加两者中少的元素,然后再同时×10

然后对最大的那个考虑之后×出来一个t<=m;

即是寻xmax*t<=m;

xmax易得为m/t

结束了

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
void solve()
{
cin>>n>>m;
int a2=0;int a5=0;
int pn=n;
while(pn&&pn%2==0){
	a2++;
	pn/=2;
}
pn=n;
while(pn&&pn%5==0){
	a5++;
	pn/=5;
}
int ans=n;int pre=1;
int mi=min(a2,a5);int ma=max(a2,a5);
for(int i=mi;i<=ma-1;i++){
	if(a2>=a5){
	  if(pre*5<=m)pre*=5;
	  else break;	
	}else{
	 if(pre*2<=m)pre*=2;
	 else break;	
	}
}
while(pre*10<=m)
{pre*=10;}
pre=m/pre*pre;
printf("%lld\n",ans*pre);
}
signed main()
{
int T;
cin>>T;
while(T--){
	solve();
}	
}

E The Humanoid

考虑dp 此刻他能杀多少人跟他获得最大血量有关,而且一定从小往大杀,因此对于血量dp

f[i][j][k]为到第i个人用了j个×2,k个×3血量最大值

考虑同层之间转移

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, h;
int dou;
int tri;
int a[200100];
int f[201000][3][3];
void solve() {
	int mx = 0;
	cin >> n >> h;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		for (int j = 0; j <= 2; j++)for (int k = 0; k <= 1; k++)f[i][j][k] = 0;
	}
	sort(a + 1, a + 1 + n);
	f[0][2][1] = 12*h;
	f[0][1][1] = 6 * h;
	f[0][0][1] = 3 * h;
	f[0][0][0] = h;
	f[0][1][0] = 2 * h;
	f[0][2][0] = 4 * h;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= 2; j++)
			for (int k = 0; k <= 1; k++) {
				if (f[i - 1][j][k] > a[i]) {
					f[i][j][k] = max(f[i][j][k], f[i - 1][j][k] + a[i] / 2);
				}
			}
		for (int j = 1; j <= 2; j++)
			for (int k = 0; k <= 1; k++) {
				if (f[i - 1][j - 1][k] * 2 > a[i]) {
				//	printf("%lld-%lld-%lld\n",j-1,k,f[i-1][j-1][k]);
					f[i][j][k] = max(f[i][j][k], f[i - 1][j - 1][k] * 2 + a[i] / 2);
				}
			}
		for (int j = 2; j <= 2; j++)
			for (int k = 0; k <= 1; k++) {
				if (f[i - 1][j - 2][k] * 4 > a[i]) {
					f[i][j][k] = max(f[i][j][k], f[i - 1][j - 2][k] * 4 + a[i] / 2);
				}
			}
		for (int j = 1; j <= 2; j++)
			for (int k = 1; k <= 1; k++) {
				if (f[i - 1][j - 1][k - 1] * 6 > a[i]) {
					f[i][j][k] = max(f[i][j][k], f[i - 1][j - 1][k - 1] * 6 + a[i] / 2);
				}
			}
		for (int j = 0; j <= 2; j++)
			for (int k = 1; k <= 1; k++) {
				if (f[i - 1][j][k - 1] * 3 > a[i]) {
					f[i][j][k] = max(f[i][j][k], f[i - 1][j][k - 1] * 3 + a[i] / 2);
				}
			}
		for (int j = 2; j <= 2; j++)
			for (int k = 1; k <= 1; k++) {
				if (f[i - 1][j - 2][k - 1] * 12 > a[i]) {
					f[i][j][k] = max(f[i][j][k], f[i - 1][j - 2][k - 1] * 12 + a[i] / 2);
				}
			}
		for (int j = 0; j <= 1; j++)
			for (int k = 0; k <= 2; k++)f[i][j][k] = max(f[i][j][k], f[i - 1][j][k]);
		for (int j = 0; j <= 2; j++) {
			for (int k = 1; k <= 1; k++)
				f[i][j][k] = max(f[i][j][k], f[i][j][k - 1] * 3);
		}
		for (int k = 0; k <= 1; k++)
			for (int j = 1; j <= 2; j++)
				f[i][j][k] = max(f[i][j][k], f[i][j - 1][k] * 2);
		for (int j = 0; j <= 2; j++)
			for (int k = 0; k <= 1; k++) {
			//	printf("%lld %lld %lld %lld\n",f[i][j][k],i,j,k);
				mx = max(mx, f[i][j][k]);
			}
		//	printf("\n");
	}
	int ans = 0;
	for (int i = 1; i <= n; i++)if (mx > a[i])ans++;
	cout << ans << endl;
}
signed main() {
	int T;
	cin >> T;
	while (T--) {
		solve();
	}
}

F  All Possible Digits

答案最大就是p因为个位加p次就可以到所有答案,然后这样只会进位一次

直接暴力判断即可

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, p;
int a[101];
void solve() {
	cin >> n >> p;
	map<int, int> mp;a[0]=0;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		mp[a[i]] = 1;
	}
	int ge = a[n];
	int sign = 0;int sign2=0;
	for(int i=0;i<p;i++){
		if(!mp[i]){sign2=1;break;}
	}
	if(!sign2){
		printf("0\n");
		return ;
	}
	for (int i = 0; i <= ge; i++) {
		if (!mp[i]){sign = 1;break;}
	}
	if (!sign) {
		int preans = p - 1;
		int cnt = 0;
		int ans;
		for (int i = preans; i >= 0; i--) {
			if (!mp[i]) {
				ans = i;
				break;
			}
			cnt++;
			if (cnt == n + 1) {
				break;
			}
		}
		printf("%lld\n",ans-ge);
		return ;
	}a[n-1]+=1;
	for(int i=n-1;i>=0;i--){
		if(a[i]>=p){
			a[i]-=p;
			a[i-1]+=1;
		}
		mp[a[i]]=1;
	}int cnt=0;int anss=0;
	for(int i=ge-1;i>=0;i--){
	if(!mp[i]){
		anss=i;
		break;
	}
	cnt++;
	if(cnt>=n+5){
		break;
	}
	}
	printf("%lld\n",anss+p-ge);
}
signed main() {
	int T;
	cin >> T;
	while (T--) {
		solve();
	}
}

G Restore the Permutation

考虑从后到前还原序列,从后到前我们需要找到小于他最大的序列,把更小的留给前面

#include <bits/stdc++.h>
using namespace std;
int n,a[200005],f;
void solve()
{
    cin>>n;set<int>s;
    for(int i=1;i<=n;f=1)s.insert(i++);
    for(int i=0;i<n/2;i++)
    {
        cin>>a[2*i+1];
        f&=s.count(a[2*i+1]);
        s.erase(a[2*i+1]);
    }
    for(int i=n/2-1;i>=0;)
    {
        auto it=s.lower_bound(a[2*i+1]);
        if(it==s.begin()){f=0;break;}
        a[2*i--]=*--it;
        s.erase(it);
    }
    if(!f)cout<<"-1 ";else
    for(int i=0;i<n;)cout<<a[i++]<<' ';
}
main()
{
    int t;cin>>t;
    while(t--)solve();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值