废话
-
370:纪念盗笔青春
-
提交记录
几个脑残错误后文会提到
3.题目:
黄黄绿蓝蓝( 幸好 370 不是“红红红红红” | “黑黑黑黑黑” )
算法: 是没有滴 贪心,前缀和
正题
CF370A
Rook, Bishop and King
签到数学题
车可以两步到达任意点 ,只需判断出发点与目标点是否在同行 | 同列
王有个性质是每次可以同时改变行列,但不必须,所以答案即为横纵坐标的差的最大值
象必须每次同时改变行列,并不能到达所有点 ( 白格只能到白格 )所以判断奇偶输出 0 ,剩下的点与车同理
#include <bits/stdc++.h>
using namespace std;
int x1,y1,x2,y2;
int main(){cin>>x1>>y1>>x2>>y2;if(x1==x2||y1==y2)cout<<1<<" ";else cout<<2<<" ";if(y1-x1==y2-x2||y1+x1==y2+x2)cout<<1<<" ";else if((y1+x1)%2!=(y2+x2)%2)cout<<0<<" ";else cout<<2<<" ";cout<<max(abs(x2-x1),abs(y2-y1));return 0;
}
CF370B
Berland Bingo
签到 不知道是什么 题
对每个卡暴力判断子集即可,因为若其他卡是他的子集,那么消他的时候那个卡也会被消掉
#include <bits/stdc++.h>
using namespace std;
const int N=105;
int n,m[N],a[N][N],o[N],maxn;
bool flag=1;
bool check(int x){int cnt=0;for(int i=1;i<=m[x];i++){cnt+=o[a[x][i]];}if(cnt==m[x])return 0;return 1;
}
int main(){cin>>n;for(int i=1;i<=n;i++){cin>>m[i];for(int j=1;j<=m[i];j++){cin>>a[i][j];maxn=max(maxn,a[i][j]);}}for(int i=1;i<=n;i++){flag=1;for(int i=1;i<=maxn;i++)o[i]=0;for(int j=1;j<=m[i];j++)o[a[i][j]]=1;for(int j=1;j<=n;j++){if(i==j||m[j]>m[i])continue;if(!check(j)){cout<<"NO"<<endl;flag=0;break;}}if(flag)cout<<"YES"<<endl;}return 0;
}
CF370C
Mittens
题解全是错的,不要看
按照颜色数量排个序,发现左边换右边就行
发现若左边右边重合则同色
同色数量:2n-2o , o 为最大颜色数量
#include <bits/stdc++.h>
using namespace std;
const int N=5e3+3;
int n,m,a[N],p,cnt,o;
struct node{int x,num;
}e[N];
bool cmp(node a,node b){return a.x>b.x;
}
int main(){cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+1+n);for(int i=1;i<=n;i++){if(a[i]!=a[i-1]){e[++cnt].num=a[i-1],e[cnt].x=p;o=max(o,p);p=0;}p++;}if(p)e[++cnt].num=a[n],e[cnt].x=p;o=max(p,o);if(o>n/2)cout<<2*n-2*o<<endl;else cout<<n<<endl;sort(e+1,e+1+cnt,cmp);n=0;for(int i=1;i<=cnt;i++)for(int j=1;j<=e[i].x;j++)a[n++]=e[i].num;for(int i=0;i<n;i++){cout<<a[i]<<" "<<a[(i+n/2)%n]<<endl;}return 0;
}
错误原因:if(p)e[++cnt].num=a[n],e[cnt].x=p;
没加最后一个块
CF370D
Broken Monitor
注意:方框==正方形
所以正方形的边长能确定,就是\(max(maxx-minx,maxy-miny)\)
然后就直接枚举正方形的左上角判断是否所有 \(w\) 都在框上
如何判断是否所有 \(w\) 都在框上?
用二维前缀和!大正方形 - 比他小一圈的正方形 = 框
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2005;
int n,m,sum[N][N],minx=0x7f7f7f7f,miny=0x7f7f7f7f,maxx,maxy,edge,num;
char a[N][N];
signed main(){cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>a[i][j];sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+(a[i][j]=='w');if(a[i][j]=='w')num++,minx=min(minx,i),maxx=max(maxx,i),miny=min(miny,j),maxy=max(maxy,j);}}edge=max(maxx-minx,maxy-miny)+1;if(edge>min(n,m)){cout<<-1;return 0;}
// cout<<num;for(int i=1;i+edge-1<=n;i++){for(int j=1;j+edge-1<=m;j++){int x1=i,y1=j,x2=i+edge-1,y2=j+edge-1,a1=x1+1,a2=x2-1,b1=y1+1,b2=y2-1;//if(i==1&&j==3)cout<<x1<<" "<<x2<<" "<<y1<<" "<<y2;if(edge>2){if(sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]==num){if(!(sum[a2][b2]-sum[a2][b1-1]-sum[a1-1][b2]+sum[a1-1][b1-1])){for(int k=1;k<=n;k++){for(int h=1;h<=m;h++){if(((k==x1&&(h<=y2&&h>=y1))||(k==x2&&(h<=y2&&h>=y1)))||((h==y1&&(k<=x2&&k>=x1))||(h==y2&&(k<=x2&&k>=x1)))){if(a[k][h]=='w')cout<<'w';else cout<<'+';}else cout<<'.';}cout<<endl;}
// for(int k=1;k<=n;k++){
// for(int h=1;h<=m;h++){
// if(a)
// }
// cout<<endl;
// }return 0;}}}else {if(sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]==num){for(int k=1;k<=n;k++){for(int h=1;h<=m;h++){if(((k==x1&&(h<=y2&&h>=y1))||(k==x2&&(h<=y2&&h>=y1)))||((h==y1&&(k<=x2&&k>=x1))||(h==y2&&(k<=x2&&k>=x1)))){if(a[k][h]=='w')cout<<'w';else cout<<'+';}else cout<<'.';}cout<<endl;}return 0;}}}}cout<<-1<<endl;return 0;
}
由提交记录得我挂了多次, 还好有拍子
错误:
- a[k][h] 写成 a[h][k]
- maxy=max(maxy,j) 写成 maxy=min(maxy,j)
- ! 不打 ()
我还是太菜了
CF370E
summer reading
cf 上的题解是 dp ,但我看不懂 ,洛谷的题解也像()一样,连代码都没有 ,故这里只讲我的贪心 ,( 有大佬会 dp 浇浇 )
记录一个 pair 的 minn maxn 表示使结果最小/最大的当前的数和量
于是可以由上一个转移过来
if(maxn[i-1].se>=2)maxn[i]=pii(maxn[i-1].fi+1,1);
else maxn[i]=pii(maxn[i-1].fi,maxn[i-1].se+1);
if(minn[i-1].se==5)minn[i]=pii(minn[i-1].fi+1,1);
else minn[i]=pii(minn[i-1].fi,minn[i-1].se+1);
目的就是判断可不可行 if(minn[i].fi>a[i]||maxn[i].fi<a[i])
到规定值时要手动修改值
maxn[i]=min(maxn[i],pii(a[i],5)); minn[i]=max(minn[i],pii(a[i],1));
手动修改值后
输出 直接取 maxn 即可
其实看代码更好理解
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
#define pii pair<int,int>
#define fi first
#define se second
pii minn[N],maxn[N];
int n,a[N],cnt[N];
int main(){cin>>n;for(int i=1;i<=n;i++)cin>>a[i];if(a[1]>1){cout<<-1;return 0;}minn[1]=maxn[1]=pii(1,1);for(int i=2;i<=n;i++){if(maxn[i-1].se>=2)maxn[i]=pii(maxn[i-1].fi+1,1);else maxn[i]=pii(maxn[i-1].fi,maxn[i-1].se+1);if(minn[i-1].se==5)minn[i]=pii(minn[i-1].fi+1,1);else minn[i]=pii(minn[i-1].fi,minn[i-1].se+1);if(a[i]){if(minn[i].fi>a[i]||maxn[i].fi<a[i]){// cout<<i;cout<<-1;return 0;}maxn[i]=min(maxn[i],pii(a[i],5));minn[i]=max(minn[i],pii(a[i],1));}// cout<<maxn[i].fi<<" "<<maxn[i].se<<" "<<minn[i].fi<<" "<<minn[i].se<<endl;}if(maxn[n].se==1)maxn[n]=pii(maxn[n].fi-1,5);if(maxn[n]<minn[n]){cout<<-1<<endl;return 0;}cout<<maxn[n].fi<<endl;a[n]=maxn[n].fi;cnt[a[n]]=1;for(int i=n-1;i;i--){a[i]=min(maxn[i].fi,a[i+1]); if(cnt[a[i]]==5) a[i]--;//手动修改cnt[a[i]]++;}for(int i=1;i<=n;i++)cout<<a[i]<<' ';return 0;
}