1. 程式人生 > >洛谷P1036 選數 P1219 八皇后

洛谷P1036 選數 P1219 八皇后

題目描述

已知 nn 個整數 x_1,x_2,…,x_nx1​,x2​,…,xn​,以及11個整數kk(k<nk<n)。從nn個整數中任選kk個整數相加,可分別得到一系列的和。例如當n=4,k=3n=4,k=3,44個整數分別為3,7,12,193,7,12,19時,可得全部的組合與它們的和為:

3+7+12=223+7+12=22

3+7+19=293+7+19=29

7+12+19=387+12+19=38

3+12+19=343+12+19=34。

現在,要求你計算出和為素數共有多少種。

例如上例,只有一種的和為素數:3+7+19=293+7+19=29。

輸入輸出格式

輸入格式:

 

鍵盤輸入,格式為:

n,kn,k(1 \le n \le 20,k<n1≤n≤20,k<n)

x_1,x_2,…,x_n (1 \le x_i \le 5000000)x1​,x2​,…,xn​(1≤xi​≤5000000)

 

輸出格式:

 

螢幕輸出,格式為: 11個整數(滿足條件的種數)。

 

輸入輸出樣例

輸入樣例#1: 複製

4 3
3 7 12 19

輸出樣例#1: 複製

1

這道題真的不難,但是真的是磨死我了,我發現我這個人真的是倔啊...能看著這個程式碼看兩天!!!!!!!!!

下面把程式碼放出來:(也不知道自己是理解了還是背住了...這類問題還要再找一個來解決一下!)

#include<iostream>
#include<cmath>

using namespace std;
int arr[20],n,k,sum=0,ans=0;
int judge[20];
bool isprime(int m)//判斷素數
{

    for(int i=2;i<=sqrt(m);i++)
    {
        if(m%i==0)return false;
    }
    return true;
}
//這裡的程式碼用到了遞迴  整個程式碼的核心
int fun(int x,int y)//x代表已經選了幾個數 y代表當前是第幾個數
{

    for(int i=y;i<n;i++)// 注意:這裡i從y開始是因為之後遞迴的時候 y每次的值都會+1 可以排除出現全排列的狀況
    {
        if(judge[i]==true)
        {
            sum+=arr[i];
            judge[i]=false;
            if(x==k-1)//這裡 k-1 是因為x從0開始的
            {
                if(isprime(sum))ans++;
            }
            else
            {
                fun(x+1,i+1);
            }
            sum-=arr[i];
            judge[i]=true;
        }
    }
}
int main(){

  cin>>n>>k;
  for(int i=0;i<n;i++)
  {
      cin>>arr[i];
      judge[i]=true;
  }
  fun(0,0);
cout<<ans<<endl;
    return 0;
}

只能說自己是個虎b了,之前有幾個地方很模糊:

1.是怎麼實現k次運算的

其實就是遞迴的思想 每次一直都是在獲得三個數相加 只是判斷這個數是否已經獲取了  所以不會獲得重複的數 

只能說大佬從i=y開始迴圈是真的很強啊啊啊!

 

 

 

題目描述

檢查一個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行、每列有且只有一個,每條對角線(包括兩條主對角線的所有平行線)上至多有一個棋子。

上面的佈局可以用序列2 4 6 1 3 5來描述,第i個數字表示在第i行的相應位置有一個棋子,如下:

行號 1 2 3 4 5 6

列號 2 4 6 1 3 5

這只是跳棋放置的一個解。請編一個程式找出所有跳棋放置的解。並把它們以上面的序列方法輸出。解按字典順序排列。請輸出前3個解。最後一行是解的總個數。

//以下的話來自usaco官方,不代表洛谷觀點

特別注意: 對於更大的N(棋盤大小N x N)你的程式應當改進得更有效。不要事先計算出所有解然後只輸出(或是找到一個關於它的公式),這是作弊。如果你堅持作弊,那麼你登陸USACO Training的帳號刪除並且不能參加USACO的任何競賽。我警告過你了!

輸入輸出格式

輸入格式:

 

一個數字N (6 <= N <= 13) 表示棋盤是N x N大小的。

 

輸出格式:

 

前三行為前三個解,每個解的兩個數字之間用一個空格隔開。第四行只有一個數字,表示解的總數。

 

輸入輸出樣例

輸入樣例#1: 複製

6

輸出樣例#1: 複製

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

說明

題目翻譯來自NOCOW。

USACO Training Section 1.5

#include <iostream>

using namespace std;

int a[100],b[100],c[100],d[100];//a表示的是行 b表示的是列 c表示的是左下到右上的  d表示左上右下
int n,total=0;//n輸入棋盤的大小  total是解的數目

void prin()
{
    if(total<=2)// 輸出的答案是前三個
    {
        for(int i=1; i<=n; i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    total++;//但是答案個數繼續上漲
}
void queen(int i)
{
    if(i>n)
    {
        prin();
        return;
    }
    else
    {
        for(int j=1; j<=n; j++)
        {
            if((!b[j])&&(!c[i+j])&&(!d[i-j+n]))//判斷列數   左上右下   左下右上(只是用某一個不同的數去代表某個指定的位置佔用還是沒佔用)
            {
                a[i]=j;//讓a[i]儲存列數
                b[j]=1;//佔了就為1
                c[i+j]=1;
                d[i-j+n]=1;
                queen(i+1);//遞迴
                //回溯
                b[j]=0;
                c[i+j]=0;
                d[i-j+n]=0;
            }
        }

    }
}
int main()
{
    cin>>n;
    queen(1);
    cout<<total;
    return 0;
}

方式錯了  初級題目刷的差不多了 開始去分模組的瞭解演算法了  等初級模組學習完再來挑戰洛谷新手boss!!!