一、问题:放苹果

题目描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

输入
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。

输出
对输入的每组数据M和N,用一行输出相应的K。

样例输入
2
6 3
7 2
样例输出
7
4
分析:

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;

int divnum(int pg,int pz);
int main(){
    int t;
    cin>>t;
    getchar();
    while(t--){
        int pg,pz;
        cin>>pg>>pz;
        cout<<divnum(pg,pz)<<endl;;
    }
    return 0;
}


int divnum(int pg,int pz){
    if(pg==0||pz==1){
        return 1;
    }
    if(pz>pg){
        return divnum(pg,pg);
    }else{
        return divnum(pg,pz-1)+divnum(pg-pz,pz);
    }
}

二、问题:N皇后

前提问题:全排列

分析:

 

代码:

N皇后问题:

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

Input:

共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。

Output:

共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。

Sample Input:

1
8
5
0

Sample Output

1
92
10
分析:
 
 
 
代码:
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<cstdlib>
using namespace std;

int n,p[100],ans[100],hashTable[100] = {false};
int ct;

void generateP(int index){
    if(index==n+1){
        ct++;
        return;
    }
    for(int x=1;x<=n;x++){
        if(hashTable[x]==false){
            bool flag = true;
            for(int pre=1;pre<index;pre++){
                if(abs(index-pre)==abs(x-p[pre])){
                    flag = false;
                    break;
                }
            }
            if(flag){
                p[index] = x;
                hashTable[x] = true;
                generateP(index+1);
                hashTable[x] = false;
            }
        }
    }
}

int main(){
    for(int i=1;i<=10;i++){
        ct = 0;
        n = i;
        generateP(1);
        ans[i] = ct;
    }
    int t;
    while(cin>>t){
        if(t==0){
            break;
        }
        cout<<ans[t]<<endl;
    }
    return 0;
}

三、问题:Prime Ring Problem

A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.

Input:n (0 < n < 20).
Output:

The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input:

6
8

Sample Output:

Case 1:
1 4 3 2 5 6
1 6 5 2 3 4

Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2

代码:

#include<iostream>
#include<algorithm>
#include<queue>
#include<string>
#include<cstdio>
#include<stack>
#include<list>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;

int n,a[30],vis[30];
int prime[40]={0,1,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0};

void dfs(int num){
    if(num==n&&prime[a[num-1]+a[0]]){
        for(int i=0;i<num-1;i++){
            printf("%d ",a[i]);
        }
        cout<<a[num-1]<<endl;
    }else{
        for(int i=2;i<=n;i++){
            if(vis[i]==0&&prime[i+a[num-1]]){
                vis[i] = 1;
                a[num++] = i;
                dfs(num);
                vis[i] = 0;
                num--;
            }
        }  
    }
};
int main(){
    int nu = 0;
    while(cin>>n){
        memset(vis,0,sizeof(vis));
        nu++;
        printf("Case %d:\n",nu);
        a[0]=1;
        dfs(1);
        printf("\n");
    }
    system("pause");
    return 0;
}

 

posted on 2020-03-03 17:42  晨曦生辉耀匕尖  阅读(178)  评论(0编辑  收藏  举报