4 1 2 5 3 5 2 9 3
NO YES 1 5 2 1 4 2 2 3 NO YES 3 1 5 9 3 2 6 73 3 4 8
这题和木棒拼接正方形很像,用相同的思路就行了。
这里注意dfs可能比较深,所以要手动开栈。#pragma comment(linker, "/STACK:102400000,102400000") 这句话加在程序最前面。
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; #define maxn 100050 #define ll long long int vis[maxn],liang,fen,n; set<int>myset[20]; set<int>::iterator it; int dfs(int x,int pos,ll len) { int i; if(x==fen)return 1; for(i=pos;i>=1;i--){ if(!vis[i]){ vis[i]=1; if(len+i<liang){ myset[x].insert(i); if(dfs(x,i-1,len+i))return 1; myset[x].erase(i); } else if(len+i==liang){ myset[x].insert(i); if(dfs(x+1,n,0))return 1; myset[x].insert(i); } vis[i]=0; } } return 0; } int main() { int i,j,T; ll num; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&fen); num=(ll)(n+1)*n/2; if(n<fen || num%fen!=0 || num/fen<n){ printf("NO\n");continue; } liang=num/fen; memset(vis,0,sizeof(vis)); for(i=0;i<=fen;i++){ myset[i].clear(); } if(dfs(0,n,0)){ printf("YES\n"); for(i=0;i<fen;i++){ printf("%d",myset[i].size()); for(it=myset[i].begin();it!=myset[i].end();it++){ printf(" %d",*it); } printf("\n"); } } else printf("NO\n"); } return 0; } /* 100 50 10 NO 40 10 YES 3 3 39 40 3 7 37 38 3 11 35 36 3 15 33 34 3 19 31 32 3 23 29 30 4 1 26 27 28 5 2 9 22 24 25 5 6 17 18 20 21 8 4 5 8 10 12 13 14 16 */
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/kirito_acmer/article/details/47405563