Problem
Description
有n个排成一圈的格子,并且已知正整数k和m,你需要往每个格子中填入一个大于等于k的正整数。将相邻的一些格子(或一个单独的格子)中的数加起来,可以产生一个新的数。
假设使用格子中的数可以产生出m,m+1,…,i,但不能产生i+1。求出往格子中填入哪些数,可以使得i尽量大。
Input
三行,每行一个正整数,分别为n,m,k。(k<=m)
Output
第一行一个正整数,表示最大的i。
下面若干行,每行为一个使i最大的填数方案,按照字典序升序排列。每行n个正整数a1,a2,…,an,表示依次往格子中填入的数,其中a1是n个数中最小的数。
注意,(1,1,2,3),(1,3,2,1),(1,2,3,1),(1,1,3,2)被认为是不同的方案,都需要输出。
Sample Input
5
2
1
Sample Output
21
1 3 10 2 5
1 5 2 10 3
2 4 9 3 5
2 5 3 9 4
Hint
数据约束:
30%的数据中,n<=5。
100%的数据中,n<=6,k<=m<=20。
Solution
思路
看到这么小的数据范围显然可以爆搜,然后为了能够过(复杂度在范围内),可以卡出搜索边界(皮..),然后这么下去就行了.
Code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
#define ll long long
#define re register
inline int gi(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return sum*f;
}
int tong[1000010],a[10],n,ans,add,reans[1000010][10],p[1000010],m,k;
int judge(){
for(re int i=n+1;i<=n*2;i++)a[i]=a[i-n];
for(re int i=1;i<=n+n;i++)p[i]=p[i-1]+a[i];
for(re int i=1;i<=p[n+n];i++)tong[i]=0;
for(re int i=1;i<=n;i++)
for(re int j=i;j<=i+n-1;j++)
tong[p[j]-p[i-1]]=1;
int i=m;
while(tong[i])i++;i--;
if(i>ans){add=0;ans=i;return 1;}
return i==ans;
}
int main(){
n=gi();m=gi();k=gi();
//...n比5小的请自行写上
if(n==5){
for(a[1]=k;a[1]<=m;a[1]++)
for(a[2]=a[1];a[2]<=k+15;a[2]++)
for(a[3]=a[1];a[3]<=k+15;a[3]++)
for(a[4]=a[1];a[4]<=k+15;a[4]++)
for(a[5]=a[1];a[5]<=k+15;a[5]++)
if(judge()){
reans[++add][0]=a[1];reans[add][1]=a[2];reans[add][2]=a[3];
reans[add][3]=a[4];reans[add][4]=a[5];
}
}
else{
for(a[1]=k;a[1]<=m;a[1]++)
for(a[2]=a[1];a[2]<=k+15;a[2]++)
for(a[3]=a[1];a[3]<=k+15;a[3]++)
for(a[4]=a[1];a[4]<=k+15;a[4]++)
for(a[5]=a[1];a[5]<=k+15;a[5]++)
for(a[6]=a[1];a[6]<=k+15;a[6]++)
if(judge()){
reans[++add][0]=a[1];reans[add][1]=a[2];reans[add][2]=a[3];
reans[add][3]=a[4];reans[add][4]=a[5];reans[add][5]=a[6];
}
}
printf("%d
",ans);
for(re int i=1;i<=add;i++)
for(re int j=0;j<n;j++)
printf("%d%c",reans[i][j],j==n-1?'
':' ');
return 0;
}