http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1005&cid=832

Problem Description

In the world line 1.048596%

梓川咲太的面前坐着野兔先辈,作为约定,只好乖乖的打开笔记本开始学习了。

“加法符号写歪了,变成了乘法符号,在算式的第三行那个地方。”樱岛麻衣突然开口。

心领神会的梓川咲太立刻发现自己正在写的题目的错误,乖乖的改正了以后却心不在焉。

毕竟,梓川咲太的眼神却很不老实,毕竟,眼前坐着野兔先辈。

“咲太,假设我给你一个正整数n,你是不是可以把它用许多不同的整数(包括它自己)去减然后把n变成0?”

樱岛麻衣开始穿上披风。

这是生气的前兆,即将没了眼福的梓川咲太只能不停的点了点头。

“那行,一个正整数n的做减法的操作过程也有很多种,比如说6就能变成6-6=0,6-1-5=0和6-2-4=0,对吧。但是不能变成6-3-3=0,因为3重复了。”

樱岛麻衣用漂亮的字体在笔记本上书写。

“当然写成6=6,6=1+5,6=2+4更好,相当于这些正整数构成一个序列{a1,a2,...,an}满足(Σai = N),(n >= 1),且这些正整数互不相同。”

“那么刚刚的例子就是{6},{1,5},{2,4}这样。”

“有没有想过把这些序列的数字乘起来呢?就像加法符号变成乘法一样,结果就是6,1x5,2x4这样......“

”就把这样操作后的结果称为M吧,对于一个正整数n,不同的拆分能得出不同的M,但M也是有最大值和最小值的。比如说刚刚那个例子,M的最大值是8,最小值是5。”

此时的梓川咲太还不知道即将到来的地狱。

“你刚刚的眼神这么不老实,大概看了几十下了吧。我就大发慈悲的写一些数字,你给我马上写出每个数字经过操作以后得出来的M的最小值和最大值。”

“不把这些写完,今晚不让你睡哦。”

麻衣打开的笔记本上密密麻麻的排列着许多数字,野兔先辈的代价实在是太大了,不过约定就是约定......

 

 

Input

第一行输入一个正整数T(T<=200),表示样例组数,接下去T行每行表示一组样例

每组样例,输入一个正整数N(1<=N<=200)

 

 

Output

输出总共T行,

每行输出两个整数,表示每个数字经过操作以后得出的数字M的最小值和最大值,用一个空格隔开

 

 

Sample Input


 

2 3 6

 

 

Sample Output


 

2 3 5 8

C++版本一

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG

using namespace std;
typedef long long ll;
const int N=200+10;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m;
int main()
{
#ifdef DEBUG
    freopen("input.in", "r", stdin);
    //freopen("output.out", "w", stdout);
#endif

    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        if(n==1||n==2){
            cout << n <<" "<<n<< endl;
            continue;
        }
        int j,i=2;
        int sum=0;
        while(sum+i<=n){
            sum+=i;
            i++;
        }
        int w=i-1;
        int m = n-sum;
        ll ans=1;
        if(m==w){  //若剩余值(n-sum)等于w
            for(int j=2;j<=i-2;j++){
                ans*=j+1;
            }
            ans*=i+1;
        }else{       //若剩余值(n-sum)小于w
            for(int j=2;j<w-m+1;j++) ans*=j;
            for(j=w-m+1;j<=i-1;j++) ans*=j+1;
        }
        cout << n-1 <<" "<<ans<< endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
}

C++版本二

https://www.cnblogs.com/MingSD/p/10050324.html

爆搜找规律。

爆搜代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod =  (int)1e9+7;
const int N = 5e5 + 100;
int sta[N];
int Max, gg;
void dfs(int b, int l, int lt, int cnt){
    if(lt == 0){
        Max = max(Max, l);
        if(gg == l){
            for(int i = 1; i < cnt; ++i)
                cout << sta[i] << ' ';
            cout << endl;
        }
    }
    for(int i = b; i <= lt; ++i){
        sta[cnt] = i;
        dfs(i+1, l*i, lt-i, cnt+1);
    }
}
int main(){
    int n;
    while(cin >> n){
        gg = -1;
        Max = 0;
        dfs(1, 1, n, 1);
        gg = Max;
        dfs(1, 1, n, 1);
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
LL Min[N], Max[N];
vector<int> v;
void init(){
    v.pb(2); v.pb(3);
    for(int i = 6; i <= 200; ++i){
        int t = v.size();
        if(v[0] != 2 && v[t-1] == v[t-2]+1)
            ++v[t-1];
        else if(v[0] != 2){
            --v[t-1];
            v.insert(v.begin(), 2);
        }
        else {
            int f = 1;
            for(int i = t-2; i >= 0; i--){
                if(v[i]+1 != v[i+1]){
                    ++v[i];
                    f = 0;
                    break;
                }
            }
            if(f) ++v[t-1];
        }
        Min[i] = i-1;
        Max[i] = 1;
        for(int x : v){
            Max[i] *= x;
        }
    }
}
vector<int> vc;
int main(){
    int T, n;
    scanf("%d", &T);
    init();
    Min[1] = Max[1] = 1;
    Min[2] = Max[2] = 2;
    Min[3] = 2; Max[3] = 3;
    Min[4] = 3; Max[4] = 4;
    Min[5] = 4; Max[5] = 6;
    while(T--){
        scanf("%d", &n);
        printf("%lld %lld\n", Min[n], Max[n]);
    }
    return 0;
}