Codeforces Round #810 (Div. 2) C.Color the Picture,大胆猜测+一点模拟
题目给定若干段颜色,还有每个颜色能涂的max个数
求能否满足相邻方格必须同一个颜色,规定相邻方格必定为4个,如果跨边界了也要考虑(比如第1行的上面的方块就是第n行
样例给出的染色方案是整列整列染过去,现场的时候思考了一下除了整列整行的染,有没有其他方案?
没有,因为如果有的话,必然存在锯齿一样的边界线,边界必有方格不能满足
那就只能整行或者整列地染色啦!——但是要怎么保证在每个颜色能染的数目>=2,且最后不会余出1行?
check的时候我优先判断当前需要几行,如果%2==1的话,那么就要先尽可能的凑出奇数,紧接着尽可能的拿最大偶数
比如说遇到了5吧,现在还缺偶数个,我们就拿4,同时tot+4,num+1,表示可支配但没选的多了一个(如果最后不够,那就把num都塞进本来可以呆的地方
如果最后已经选取的tot+num>=need,就符合条件~
小tips:如果没有开longlong的话,累加到符合条件就要break了,不会会爆炸hhh
#include<bits/stdc++.h> using namespace std; int n,m,k; int r[int(1e5)+7],a[int(1e5)+7]; bool cmp(int a,int b){return a>b;} bool work(int n,int m){ for(int i=1;i<=k;i++) r[i]=a[i]/n; sort(r+1,r+k+1,cmp); int need=0,tot=0,left=0; need=m%2; for(int i=1;i<=k;i++){ if(r[i]<=1) break; if(tot>=m) break; if(tot+1==m) break; if(r[i]%2==1){ if(need==1) {tot+=r[i];need=0;} else {tot+=r[i]-1;left++;} } else { if(need==1){ if(r[i]>=4){ tot+=r[i]-1;need=0;left++; } else if(r[i]==2) { tot+=r[i]; } } else tot+=r[i]; } } if(tot+left>=m) return true; else return false; } void solve(){ cin>>n>>m>>k; for(int i=1;i<=k;i++) cin>>a[i]; if(work(n,m)||work(m,n)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } int main(){ //freopen("lys.in","r",stdin); int t; cin>>t; while(t--){ solve(); } }