标签:ble can clu 贪心 div end pac ret .net
https://vjudge.net/problem/UVA-12520
题意:n*n网格中染色m个格子,染色格子的最长轮廓线
贪心
将格子分为4类
1、隔一个选一个,互不相邻的格子
2、4个角上的格子
3、边界除角的格子
4、内部的格子
4类从上到下依次选
1对答案有4的贡献
2对答案无贡献
3对答案有-2的贡献
4对答案有-4的贡献
对n奇偶分类讨论
当n为奇数时,在分左上角的格子在第1类还是第2类讨论
#include<cstdio> #include<algorithm> using namespace std; int main() { freopen("data.txt","r",stdin); freopen("my.txt","w",stdout); long long ans1,ans2,n,sum,rest,now,tmp; while(scanf("%lld%lld",&n,&sum)!=EOF) { if(!n) return 0; if(n&1) { if(sum<=n*n>>1 || sum<=n*n/2+1) { printf("%lld\n",sum<<2); continue; } if(sum<=n*n/2+4) ans1=n*n/2*4; else { tmp=sum-4-n*n/2; ans1=n*n/2<<2; rest=n/2-1<<2; if(tmp<=rest) ans1-=tmp<<1; else { ans1-=rest<<1; tmp-=rest; ans1-=tmp<<2; } } ans2=n*n/2+1<<2; now=n*n/2+1; rest=n/2<<2; if(sum-now<=rest) ans2-=sum-now<<1; else { ans2-=rest<<1; now+=rest; ans2-=sum-now<<2; } printf("%lld\n",max(ans1,ans2)); } else { if(sum<=n*n>>1) { printf("%lld\n",sum<<2); continue; } if(sum<=n*n/2+2) { printf("%lld\n",n*n/2*4); continue; } ans1=n*n>>1<<2; tmp=sum-n*n/2-2; rest=n/2-1<<2; if(tmp<=rest) ans1-=tmp<<1; else { ans1-=rest<<1; tmp-=rest; ans1-=tmp<<2; } printf("%lld\n",ans1); } } }
同一种思路大佬的写法就是短
#include<iostream> #include<cstdio> using namespace std; typedef long long ll; ll l,n,a,b,c,ans; ll cal() { if(n<=a) return n*4; if(n<=a+b) return a*4; if(n<=a+b+c) return a*4-(n-a-b)*2; return a*4-c*2-(n-a-b-c)*4; } int main() { freopen("data.txt","r",stdin); freopen("std.txt","w",stdout); while(cin>>l>>n,l||n) { if(l%2==0) { a=l*l/2; b=2; c=l/2-1<<2; ans=cal(); } else { a=l*l/2; b=l==1 ? 1:4; c=l==0 ? 0:(l-3)/2*4; ans=cal(); a=l*l/2+1; b=0; c=(l-1)/2*4; ans=max(ans,cal()); } cout<<ans<<endl; } }
标签:ble can clu 贪心 div end pac ret .net
原文地址:http://www.cnblogs.com/TheRoadToTheGold/p/7465031.html