hdu 4671 瞎搞
题意:每个用户对数据库的查询请求都会首先用该数据库的服务器序列的第一个去执行任务,若第一个坏了,就由第二个执行。最多只会坏一个服务器。要求是考虑最多坏一个的情况下,所有服务器中执行用户查询的数目最大值与最小值之差不能超过1。
思路:
对于n>=m的情况,很容易能解决掉,关键是n<m就不好处理了。我的方法应该是最挫的,直接先给确定每个序列的第一个数字为1~~n的循环。第二个就每次放一个数,用贪心判断是否合法,合法就在放下一个序列的第二个数。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; int ans[110][3],pre[110],vi[110],num[110],n,m; struct Que{ int val,c; int operator <(const Que &temp) const { return c>temp.c; } }; int Ok() { int i,j; int cnt[110]; int Max,Min; for(i=1;i<=n;i++) { memset(cnt,0,sizeof(cnt)); Max=0,Min=1000; for(j=1;j<=m;j++) if(ans[j][1]==i) cnt[ans[j][2]]++; else cnt[ans[j][1]]++; for(j=1;j<=n;j++) { if(j==i) continue; Max=max(Max,cnt[j]); Min=min(Min,cnt[j]); } if(Max-Min>1) return 0; } return 1; } void Out2() { int i,j; int x=0; int Max=0; for(i=1;i<=m;i++) ans[i][1]=x%n+1,x%=n,x++,num[x]++; for(i=1;i<=m;i++) { for(j=1;j<=n;j++) if(ans[i][1]!=j) { ans[i][2]=j; if(Ok()) break; ans[i][2]=0; } } for(i=1;i<=m;i++) { memset(vi,0,sizeof(vi)); x=1; vi[ans[i][1]]=vi[ans[i][2]]=1; printf("%d %d",ans[i][1],ans[i][2]); for(j=1;j<=n-2;j++) { while(vi[x]) x++; printf(" %d",x); vi[x]=1; } printf("\n"); } } int main() { int i,j; while(scanf("%d%d",&n,&m)!=EOF) { memset(num,0,sizeof(num)); memset(ans,0,sizeof(ans)); for(i=1;i<=n;i++) pre[i]=i; int x; if(n>=m) { for(i=1;i<m;i++){ printf("%d %d",i,n); x=1; for(j=1;j<=n-2;j++){ if(x==i){ printf(" %d",x+1); x+=2; } else printf(" %d",x++); } printf("\n"); } if(m==n){ printf("%d",m); for(i=1;i<n;i++) printf(" %d",i); printf("\n"); } else{ printf("%d %d",m,n); x=1; for(i=1;i<=n-2;i++){ if(i==m){ printf(" %d",x+1); x+=2; } else printf(" %d",x++); } printf("\n"); } } else{ Out2(); } } return 0; }