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;
}