「CJOJ2737」Circle

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();
    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\n",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?'\n':' ');
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/cjgjh/p/9499706.html