有意思的是,所有的三阶幻方,都可以通过这样一个九宫格进行若干镜像和旋转操作之后得到。现在小Hi准备将一个三阶幻方(不一定是上图中的那个)中的一些数组抹掉,交给邻居家的小朋友来进行还原,并且希望她能够判断出究竟是不是只有一组解。
而你呢,也被小Hi交付了同样的任务,但是不同的是,你需要写一个程序~
输入
输入仅包含单组测试数据。
每组测试数据为一个3*3的矩阵,其中为0的部分表示被小Hi抹去的部分。
对于100%的数据,满足给出的矩阵至少能还原出一组可行的三阶幻方。
输出
如果仅能还原出一组可行的三阶幻方,则将其输出,否则输出“Too Many”(不包含引号)。
样例输入
0 7 2
0 5 0
0 3 0
样例输出
6 7 2
1 5 9
8 3 4
比较简单的DFS。
AC代码:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int MAXN=10; int graph[MAXN],vis[MAXN],ans[MAXN]; int flag=0; bool isok() { for(int i=1;i<=7;i+=3) { if((graph[i]+graph[i+1]+graph[i+2])!=15) return false; } for(int i=1;i<=3;i++) { if((graph[i]+graph[i+3]+graph[i+6])!=15) return false; } if((graph[1]+graph[5]+graph[9])!=15||(graph[3]+graph[5]+graph[7])!=15) return false; return true; } void dfs(int pos) { if(pos==10&&isok()) { flag++; if(flag==1) { memcpy(ans,graph,sizeof(graph)); return; } } if(graph[pos]) dfs(pos+1); else { for(int i=1;i<=9;i++) { if(vis[i]) continue; vis[i]=1; graph[pos]=i; dfs(pos+1); vis[i]=0; graph[pos]=0; } } } int main() { memset(vis,0,sizeof(vis)); for(int i=1;i<=9;i++) { scanf("%d",&graph[i]); vis[graph[i]]=1; } dfs(1); if(flag==1) { for(int i=1;i<=9;i++) { printf("%d%c",ans[i],(i%3==0)?'\n':' '); } } else printf("Too Many\n"); }题目2 : 优化延迟
#include<cstdio> #include<queue> using namespace std; const int MAXN=100005; int P[MAXN],N; long long Q; bool isOk(int value) { long long cnt=0; int index=1; priority_queue<int> queue; for(int i=1;i<=N;i++) { if(queue.size()==value) { int temp=queue.top(); queue.pop(); cnt+=temp*index++; } queue.push(P[i]); } while(queue.size()) { int temp=queue.top(); queue.pop(); cnt+=temp*index++; } if(cnt<=Q) return true; else return false; } int main() { while(scanf("%d%lld",&N,&Q)>0) { for(int i=1;i<=N;i++) scanf("%d",&P[i]); int minn=1;int maxn=100000; while(minn<=maxn) { int mid=(minn+maxn)/2; if(isOk(mid)) maxn=mid-1; else minn=mid+1; } if(minn>100000) minn=-1; printf("%d\n",minn); } return 0; }题目3 : 建造基地
#include<cstdio> #include<algorithm> #define INF 1<<30 using namespace std; typedef long long ll; int main() { int Q,N,M,K,T; int a[110],b[110]; ll dp[10010]; //dp[i]表示价值为i时的最小成本 while(~scanf("%d",&Q)) { while(Q--) { ll res=0; scanf("%d%d%d%d",&N,&M,&K,&T); for(int i=1;i<=M;i++) scanf("%d",&a[i]); for(int i=1;i<=M;i++) scanf("%d",&b[i]); for(int u=1;u<=N;u++) { for(int i=1;i<10010;i++) dp[i]=INF; dp[0]=0; for(int i=1;i<=M;i++) { for(int j=0;j<=K;j++) { if(j+b[i]>K) dp[K]=min(dp[K],dp[j]+a[i]); else dp[j+b[i]]=min(dp[j+b[i]],dp[j]+a[i]); } } res+=dp[K]; //将每级累加 for(int v=1;v<=M;v++) b[v]/=T; } if(res>=INF) puts("No Answer"); else printf("%lld\n",res); } } return 0; }题目4 : 舰队游戏
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int const MAX=1e3+5; int N,M,T,S; int sz_a; int sz_b; //对空飞机的数量 int sz_c; //对舰飞机的数量 int b[MAX],B[MAX],c[MAX],C[MAX]; struct A { int num,pos; }a[5][5],temp[20]; bool cmp(A x,A y) { return x.num>y.num; } //计算对空值 int cal_air(int k) { memset(temp,0,sizeof(temp)); sz_a=0; //搭载了多少架对空飞机 for(int i=0;i<N;i++) { for(int j=0;j<M;j++) { if(k&(1<<(i*M+j))) { temp[sz_a++].num=a[i][j].num; } } } sort(temp,temp+sz_a,cmp); int res=0; for(int i=0,j=0;i<sz_a&&j<sz_b;i++,j++) res+=temp[i].num*B[j]; return res; } //计算对舰值 int cal_ship(int k) { memset(temp,0,sizeof(temp)); sz_a=0; //搭载了多少架对舰飞机 for(int i=0;i<N&&sz_a<=sz_c;i++) { for(int j=0;j<M&&sz_a<=sz_c;j++) { if(!(k&(1<<(i*M+j)))) //如果已经搭载了对空飞机就不能搭载对舰飞机 { temp[sz_a].num=a[i][j].num; temp[sz_a++].pos=a[i][j].pos; //后面还要用到舰艇的信息 } } } sort(temp,temp+sz_a,cmp); int res=0; for(int i=0,j=0;i<sz_a&&j<sz_c;i++,j++) res+=temp[i].num*C[j]; return res; } //计算能不能满足每一艘舰船至少装备一架对舰飞机 bool judge_ship() { //枚举每一艘舰艇 for(int i=0;i<N;i++) { bool flag=false; for(int j=0;j<M&&!flag;j++) { for(int k=0;k<min(sz_a,sz_c)&&!flag;k++) { if(((1<<(i*M+j))&temp[k].pos)) flag=true; } } if(!flag) return false; } return true; } int main() { int Q; scanf("%d",&Q); while(Q--) { sz_b=0; sz_c=0; scanf("%d%d%d%d",&N,&M,&T,&S); for(int i=0;i<N;i++) { for(int j=0;j<M;j++) { scanf("%d",&a[i][j].num); a[i][j].pos=(1<<(i*M+j)); } } for(int i=0;i<T;i++) { scanf("%d",&b[i]); if(b[i]) B[sz_b++]=b[i]; } for(int i=0;i<T;i++) { scanf("%d",&c[i]); if(c[i]) C[sz_c++]=c[i]; } sort(B,B+sz_b,greater<int>()); sort(C,C+sz_c,greater<int>()); int ans=-1,tot=1<<(N*M); // N艘舰船,每艘舰船M个装备,每个装备有装载和未装载两种情况,一共枚举2*n*m种可能 bool has=false; for(int i=0;i<tot;i++) { if(cal_air(i)>=S) { int temp=cal_ship(i); if(temp>ans||(temp==ans&&!has)) { ans=temp; has=judge_ship(); } } } if(ans==-1) printf("Not Exist\n"); else printf("%d\n%s\n",ans,has?"Yes":"No"); } }