noip第17課作業


1.  召見騎士

【問題描述】

某王國有5位騎士,每位騎士都有自己的編號,且這個王國的編號都為奇數,分別為1,3,5,7,9,在國王召見他們之前他們都必須經過只能從一邊進出的長廊,長廊的寬度只能坐一個人。2018年1月1日這天,所有騎士依照編號從小到大的次序提前在長廊的入口等待,且只有當前面的人進入長廊后,后面的人才能進入長廊。國王想要召見一些騎士,把他們的編號寫在紙上,讓侍衛去宣傳召見,問國王寫的召見編號是否合理?

【輸入格式】

輸入一個編號序列。

【輸出格式】

如果合理,輸出“YES”,如果不合理,輸出“NO”。

【輸入樣例】

3 1 9 7 5

【輸出樣例】

YES

【輸入樣例】

5 1 3 7 9

【輸出樣例】

NO

#include <iostream>
using namespace std;
const int N = 1010;
int stack[N],a[N];
int top,n;
int main() {
    for (int i = 1; i <= 5; ++ i) {
        cin >> a[i];
    }
    top = 0;
    for (int i = 1,cur = 1; i <= 5; i++) {
        while (cur <= a[i]) {
            stack[++top] = cur;
            cur = cur+2; 
        }
        if (stack[top] == a[i]) {
            --top;
        } else {
            cout << "NO" << endl;
            return 0;
        }
    }
    cout << "YES" << endl;
    return 0;
}

2.  出棧順序

【問題描述】

給定一個由n個元素構成的序列,你需要將其中的元素按順序壓入一個大小為c的棧並彈出。元素按它們的出棧順序進行排列,會得到一個新的序列。我們知道,這樣的序列會有很多種,請輸出所有新序列中第一個元素最小的序列(若第一個元素最小的序列有多個,則令第二個盡可能小;若仍有多個,則令第三個最小,以此類推)。

【輸入格式】

第一行,兩個數n,c;

第二行n個數,為序列中n個元素的值。

【輸出格式】

輸出n個數,為滿足要求的序列。

【樣例輸入】  

6 3

5 2 3 8 7 4

【樣例輸出】

2 3 5 4 7 8

#include<iostream>
#include <climits>
using namespace std;
int n,c,flag,m;
int stack[10005],top;
int num[10005];
int main() {
    int i,j;
    cin >> n>> c;
    for(i=1; i<=n; i++)
        cin >> num[i];
    //6 3
    //5 2 3 8 7 4 
    while(m<n) {  // 變量m表示輸出的數的個數
        if(flag<n) {   //flag表示棧內數字的個數 
            int minn=INT_MAX,q;
            //根據棧的空余位置,找出數組的前幾項(例如開始棧為空,空余3個位置那么我們就看數字前三位的最小值) 
            for(i=flag+1; i<=flag+c-top && i<=n; i++) {
                if(num[i]<minn) {
                    minn=num[i];
                    q=i;
                }
            }
            //如果棧為空,我們直接把q項數據入棧 
            if(!top) {
                for(i=flag+1; i<q; i++) {
                    stack[++top]=num[i];
                }
                flag = q;
                cout << num[flag]<<" ";  //輸出棧頂的最小值 
                m++;
            } else {  //如果棧不為空 
                //如果要入棧的數字比棧頂元素大,輸出棧頂元素
                if(stack[top]<num[q]) {
                    cout << stack[top--]<<" ";
                    m++;
                } else {   //如果要入棧數字比棧頂元素小,把該數字入棧 
                    for(i=flag+1; i<q; i++) {
                        stack[++top]=num[i];
                    }
                    flag = q;
                    cout << num[flag]<<" ";
                    m++;
                }
            }
        } else {  //如果滿了,那么把棧里面的數據全部輸出 
            while(top) {
                cout << stack[top--]<<" ";
                m++;
            }
        }
    }
    return 0;
}

1.  回文素數

【問題描述】

一個數如果從左往右讀和從右往左讀數字是相同的,則稱這個數是回文數,如121,1221,15651都是回文數。給定位數n,找出所有既是回文數又是素數的n位十進制數。(注:不考慮超過整型數范圍的情況)。

輸入:位數n,其中1<=n<=9。

輸出:第一行輸出滿足條件的素數個數,第二行按照從小到大的順序輸出所有滿足條件的素數,兩個數之間用一個空格區分。

【樣例輸入1】

1

【樣例輸出1】

4

2 3 5 7                    

【樣例輸入2】

3

【樣例輸出2】

15

101 131 151 181 191 313 353 373 383 727 757 787 797 919 929

#include<iostream>
using namespace std;
int n;
long long a,b,res[50000],cnt;
//計算並返回10^x
long long mypow(int x) { 
    long long ans=1;
    for(int i=1; i<=x; i++) {
        ans=ans*10;
    }
    return ans;
}
//關鍵是構造回文數 例如:n等於123,返回12321這樣一個回文數
long long huiwen(long long x) { 
    long long ans=x;
    x=x/10;
    while(x>0) {
        ans=ans*10+x%10;
        x/=10;
    }
    return ans;
}
//判斷是否為素數 
bool is_prime(long long x) {
    for(long long i=2; i*i<=x; i++) {
        if(x%i==0) {
            return false;
        }
    }
    return true;
}
int main() {
    cin>>n;
    if(n==1) {
        cout << 4 << endl;
        cout << "2 3 5 7" << endl;
    } else if(n==2) {
        cout << 1 << endl;
        cout  << 11 << endl;
    } else if(n%2==0) {
        cout << 0 << endl;
    } else {
        cnt=0;
        n=(n+1)/2;
        //構造[a,b)區間內的回文數
        a=mypow(n-1);
        b=mypow(n);
        for(long long i=a; i<b; i++) {
            long long t=huiwen(i);
            if(is_prime(t)) {
                res[cnt++]=t;
            }
        }
        cout<<cnt<<endl;
        for(int i=0; i<cnt; i++) {
            cout<<res[i]<<" ";
        }
        cout<<endl;
    }

}

2.  棧的操作

【問題描述】

現在有四個棧,其中前三個為空,第四個棧從棧頂到棧底分別為1,2,3,…,n。每一個棧只支持一種操作:彈出並壓入。它指的是把其中一個棧A的棧頂元素x彈出,並馬上壓入任意一個棧B中。但是這樣的操作必須符合一定的規則才能進行。規則1:A棧不能為空。規則2:B棧為空或x比B棧棧頂要小。

對於給定的n,請你求出把第四個棧的n個元素全部移到第一個棧的最少操作次數。

由於最少操作次數可能很多,請你把答案對2018取模。

 

 

【輸入格式】

    一行,一個n

【輸出格式】

一行,一個正整數,為把最少操作次數mod 2018的值

【樣例輸入】  

2

【樣例輸出】

3

#include<iostream>
#include<cstdio>
using namespace std;
const long long mod=1000007;
long long  n,ans;
int main() {
    cin >> n;
    long long to;
    for(long long i=1; i<=n; ++i) {
        if((i+1)*i>=2*n) {
            to=i-1;
            break;
        }
    }
    //get to,求出幾大塊完整的相同項
    long long last=1;
    for(long long i=1; i<=to; ++i) {
        long long it=i*last;
        it%=mod;
        ans+=it;
        ans%=mod;
        last*=2;
        last%=mod;
    }
    //累和
    long long need=2*n-to*to-to;
    need/=2;
    //求出剩下項
    ans+=1*(need*last)%mod;
    //取模
    ans%=mod;
    cout<<ans<<endl;
}
#include<iostream>
#include<cstdio>
using namespace std;
const long long mod=1000007;
long long  n,ans;
int main() {
    cin >> n;
    long long to;
    for(long long i=1; i<=n; ++i) {
        if((i+1)*i>=2*n) {
            to=i-1;
            break;
        }
    }
    //get to,求出幾大塊完整的相同項
    long long last=1;
    for(long long i=1; i<=to; ++i) {
        long long it=i*last;
        it%=mod;
        ans+=it;
        ans%=mod;
        last*=2;
        last%=mod;
    }
    //累和
    long long need=2*n-to*to-to;
    need/=2;
    //求出剩下項
    ans+=1*(need*last)%mod;
    //取模
    ans%=mod;
    cout<<ans<<endl;
}

3.  波蘭表達式

【問題描述】

波蘭表達式是一種把運算符前置的算術表達式,例如普通的表達式2 + 3的波蘭表示法為+ 2 3。波蘭表達式的優點是運算符之間不必有優先級關系,也不必用括號改變運算次序,例如(2 + 3) * 4的波蘭表示法為* + 2 3 4。本題求解波蘭表達式的值,其中運算符包括+ - * /四個。

【輸入格式】

輸入為一行,其中運算符和運算數之間都用空格分隔,運算數是浮點數。

【輸出格式】

輸出為一行,表達式的值。可直接用printf("%f\n", v)輸出表達式的值v。

【樣例輸入】

* + 11.0 12.0 + 24.0 35.0

【樣例輸出】

1357.000000

提示:可使用atof(str)把字符串轉換為一個double類型的浮點數。atof定義在math.h中

#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;
int main() {
    char str[1001][101]= {};
    int s=1,i = 1;
    int a1,a2;
    a1=a2=0;
    double a[1001]= {};
    int p=0;
    while(cin>>str[s])
        s++;
    s--;
    for(i=s; i>=1; i--) {
        if(strcmp(str[i],"+")==0||strcmp(str[i],"-")==0
                ||strcmp(str[i],"*")==0||strcmp(str[i],"/")==0) {
            if(strcmp(str[i],"-")==0) {
                a[p-1]=a[p]-a[p-1];
                a[p]=0;
                p--;
            }
            if(strcmp(str[i],"+")==0) {
                a[p-1]=a[p]+a[p-1];
                a[p]=0;
                p--;
            }
            if(strcmp(str[i],"*")==0) {
                a[p-1]=a[p]*a[p-1];
                a[p]=0;
                p--;
            }
            if(strcmp(str[i],"/")==0) {
                a[p-1]=a[p]/a[p-1];
                a[p]=0;
                p--;
            }
        } else {
            a[++p]=atof(str[i]);
        }
    }
    printf("%f\n",a[1]);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM