打codeforces时出现的沙雕错误

15 篇文章 0 订阅
14 篇文章 0 订阅

Codeforces Round #554 (Div. 2) B. Neko Performs Cat Furrier Transform
思路:题中数据范围最大不超过1e6,化为二进制长度不超过20位,所以可以每次把最靠近最高位的0变成1,直接模拟即可
错误点:我的代码中模拟过程使用for循环时,只有奇数操作需要i++,偶数不需要,直到最后都没发现,实现掉分
更正后代码

#include <bits/stdc++.h>

using namespace std;

int ans[105];


int main() {
	int  x;
	cin >> x;
	int t=x,cnt=0;
	while(t) {
		t>>=1;
		cnt++;
	}
	int pos=0;
	int ct=1;
	if(x==((1<<cnt)-1))
	{
		cout <<0<<endl;
	}
	else {
		for(int i=1;x!=((1<<cnt)-1);) {
			if(ct%2) {
				if(x&(1<<(cnt-i))) {
					i++;
					continue;
				}
				x^=((1<<(cnt-i+1))-1);
				ans[pos++]=cnt-i+1;
				ct++;
				i++;
			}
			else {
				x+=1;
				ct++;
			}
		}
		cout <<ct-1<<endl;
		for(int i=0;i<pos;i++) {
			if(i>0)cout <<" ";
			cout <<ans[i];
		}
		cout << endl;
	}
	return 0;
}

Codeforces Round #553 (Div. 2)B. Dima and a Bad XOR
https://codeforces.com/contest/1151/problem/B
思路:比赛中我使用背包dp,调了好久后过了。官方题解是先假设答案为矩阵每行第一列数,如可行直接输出,如果不行,找每行中与第一列的数不同的数(在在某一行找到即可),找到就输出
错误点:dp层数从0开始,以至于在输出结果时要特判,所以dp层数还是从1开始设置比较好
代码

#include <bits/stdc++.h>

using namespace std;

int a[505][505];
int dp[505][2024];
int ans[505];

int main() {
	int n,m;
	ios::sync_with_stdio(0);
	cin >> n >>m;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
			cin >>a[i][j];
	}
	for(int i=0;i<m;i++)dp[0][a[0][i]]=1;
	for(int i=1;i<n;i++) {
		for(int j=0;j<m;j++) {
			for(int k=0;k<=1024;k++) {
				dp[i][k]|=dp[i-1][k^a[i][j]];
			}
		}
	}
	for(int i=1;i<=1024;i++)
		if(dp[n-1][i]) {
			int t=i;
			for(int k=n-1;k>=0;k--) {
				for(int j=0;j<m;j++) {
					if(k>0&&dp[k-1][t^a[k][j]]) {
						t=t^a[k][j];
						ans[k]=j+1;
						break;
					}
					else if(k==0&&t==a[k][j]){
						ans[k]=j+1;
						break;
					}
				}
			}
			cout <<"TAK"<<endl;
			for(int i=0;i<n;i++) {
				if(i>0)cout <<" ";
				cout <<ans[i];
			}
			cout << endl;
			return 0;
		}
	cout <<"NIE"<<endl;
	return 0;
}

Codeforces Round #553 (Div. 2)D. Stas and the Queue at the Buffet
思路:我当时是先假设n为2,分别是(ai,bi)(ai+1,bi+1),比较两种排列顺序的答案可推出,n=2时贪心条件为ai+bi+1>ai+1+bi,用迭代法可以证明n>2时也成立(这里是我的口胡,如有不妥请指正) 官方题解是直接根据假设有n个的结果式进行贪心

错误点:当时看错题了,看成左边乘右距离,右边乘左距离了,实现贪心失败
更正后代码

#include <bits/stdc++.h>

using namespace std;


const int maxn=1e5+5;

struct node {
	long long a,b;
	bool operator <(const node d)const {
		return a+d.b>d.a+b;
	}
}c[maxn];

int main() {
	int n;
	ios::sync_with_stdio(0);
	cin >> n;
	for(int i=0;i<n;i++) {
		cin >>c[i].a>>c[i].b;
	}
	long long ans=0;
	sort(c,c+n);
	for(int i=0;i<n;i++) {
		//cout <<c[i].a<<endl;
		int t=i+1;
		ans+=c[i].a*(t-1)+c[i].b*(n-t);
	}
	cout << ans <<endl;
	return 0;
}

Codeforces Round #552 (Div. 3) C. Gourmet Cat
思路:先把a,b,c中超过一个周期的数量减掉,然后进行模拟
错误点:看错条件把71e8看成71e7了,然后一直改,卡到最后才过

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main() {
	ll a,b,c;
	ios::sync_with_stdio(0);
	cin >> a >> b >> c;
	ll ans=0;
	for(int i=1;i<=7;i++) {
		ll ta=0,tb=0,tc=0;
		ll a1=a,b1=b,c1=c;
		ll cnt=0;
		ll  t=min(a1,min(b1,c1));
		if(t>=7) {
			for(int j=i;j<=i+6;j++) {
				int t=j%7+1;
				if(t==1||t==4||t==7)ta++;
				else if(t==2||t==6)tb++;
				else tc++;
			}
			ll l=min(a1/ta,min(b1/tb,c1/tc));
			a1-=l*ta;
			b1-=l*tb;
			c1-=l*tc;
			cnt+=l*7;
		}
		ta=a1,tb=b1,tc=c1;
		for(int j=i;;j++) {
			ll t=j%7+1;
			if(t==1||t==4||t==7)
			{
				if(!ta) {
					ans=max(ans,cnt);
					break;
				}
				ta--;
			}
			else if(t==2||t==6)
			{
				if(!tb) {
					ans=max(ans,cnt);
					break;
				}
				tb--;
			}
			else 
			{
				if(!tc) {
					ans=max(ans,cnt);
					break;
				}
				tc--;
			}
			cnt++;
		}
		ans=max(ans,cnt);
	}
	cout << ans << endl;
	return 0;
}

Codeforces Round #555 (Div. 3)C2 - Increasing Subsequence (easy version)
https://codeforces.com/contest/1157/problem/C1
思路:设置两个变量代表数组边界值,以贪心思想直接两边向中间移动即可
错误点:while循环条件中设置成left<right,使最后的字符不能输出,以致代码改慢了,实现掉分
c++代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn=2e5+5;

int st[maxn],a[maxn];

int main() {
	int n;
	ios::sync_with_stdio(0);
	cin >> n;
	for(int i=0;i<n;i++) {
		cin >> a[i];
	}
	int  l=0,r=n-1,pos=0;
	st[0]=0;
	string s;
	while(l<=r) {
		if(a[l]<a[r]) {
			if(a[l]>st[pos]) {
				st[++pos]=a[l++];
				s+="L";
			}
			else if(a[r]>st[pos]){
				st[++pos]=a[r--];
				s+="R";
			}
			else break;
		}
		else {
			if(a[r]>st[pos]) {
				st[++pos]=a[r--];
				s+="R";
			}
			else if(a[l]>st[pos]){
				st[++pos]=a[l++];
				s+="L";
			}
			else break;
		}
	}
	cout <<s.length()<<endl;
	cout <<s;
	cout <<endl;
	return 0;
}

Codeforces Round #556 (Div. 2)C. Prefix Sum Primes
思路:先打素数表,然后从0遍历到数列总和sum,以贪心思想,尽量在当前i不是素数时输出2。
错误点:素数表开小了,需要4e5,开的3e5,实现fst,进而掉分
更正后代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn=4e5+5;

int a[3];
bool vis[maxn];

vector <int> ans;

int main() {
	int n;
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int m=sqrt(maxn);
	for(int i=2;i<=m;i++)if(!vis[i]) {
		for(int j=i*i;j<maxn;j+=i)vis[j]=1;
	}
	cin >>n;
	int sum=0;
	for(int i=0;i<n;i++) {
		int t;
		cin >> t;
		sum+=t;
		a[t]++;
	}
	vis[1]=1;
	for(int i=0;i<sum;i++) {
		if((vis[i+1]&&a[2])||!a[1]) {
			a[2]--;
			ans.push_back(2);
			i++; 
		}
		else {
			a[1]--;
			ans.push_back(1);
		}
	}
	for(int i=0;i<ans.size();i++) {
		if(i>0)cout <<" ";
		cout <<ans[i];
	}
	cout << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值