2020年浙江理工大學算法藝術與信息學競賽期末測試

總結:學過算法的可以水學分 沒學過的不太好水高分 一般c語言學了70-80分沒問題 但是90-100有難度 自行斟酌

問題 A: 賭徒

題目描述

有n個賭徒打算賭一局。規則是:
每人下一個賭注,賭注爲非負整數,且任意兩個賭注都不相同。勝者爲賭注恰好是其餘任意三個人的賭注之和的那個人。如果有多個勝者,我們取賭注最大的那個爲最終勝者。
例如,A,B,C,D,E分別下賭注爲2、3、5、7、12,最終勝者是E,因爲12=2+3+7。

輸入

輸入包含多組測試數據。每組首先輸入一個整數n(1<=n<=1000),表示賭徒的個數。
接下來n行每行輸入一個非負整數b(0<=b<32768),表示每個賭徒下的賭注。
當n=0時,輸入結束。

輸出

對於每組輸入,輸出最終勝者的賭注,如果沒有勝者,則輸出no solution。

簡單思路

直接暴力 但是我總覺得數據稍微大點這題絕對不能這麼做

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int n;
    int a[1111];
    while(cin>>n && n){
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+1+n,cmp);
        int flag=0;
        for(int t=1;t<=n;t++){
            for(int i=t+1;i<=n;i++){
                for(int j=i+1;j<=n;j++){
                    for(int k=j+1;k<=n;k++){
                        if(a[i]+a[j]+a[k]==a[t]){
                            cout<<a[t]<<endl;
                            flag=1;
                            break;
                        }
                    }
                    if(flag) break;
                }
                if(flag) break;
            }
            if(flag) break;
        }
        if(!flag)
            cout<<"no solution\n";
    }
    return 0;
}

問題 B: ASCII碼

題目描述

相信大家一定都知道大名鼎鼎的ASCII碼,這次給你的任務是輸入數字(表示ASCII碼),輸出相對應的字符信息。

輸入

第一行爲一個整數T(1<=T<=1000)。
接下來包括T個正整數,由空白符分割。(空白符包括空格、換行、製表符)
這些整數不會小於32。

輸出

在一行內輸出相應的字符信息。(注意不要輸出任何多餘的字符)

簡單思路

直接強轉就行了

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
    int t;
    while(cin>>t){
        while(t--){
            int a;
            cin>>a;
            cout<<(char)a;
        }
        cout<<endl;
    }
    system("pause");
    return 0;
}

問題 C: 期末成績

題目描述

又到學期末,小明迎來了又一次的期末考試。雖然每學期都要考試,但是這次期末考試對小明來說意義重大。因爲小明愛慕已久的女神說,如果小明這次考了全班前三名就做他女朋友。雖說小明沒有十足的信心,但是女神的話不能不聽啊。
考完試後,小明拿到了全班的成績單,這張成績單是按學號順序排好的。小明很想知道班裏到底有多少人分數比他高,現在就請你幫幫他,幫他數一下到底有多少人的分數比他高吧。

輸入

輸入數據的第一行是一個正整數T,表示測試數據的組數,接下來有T組測試數據。
每組數據包括兩行。
第一行有兩個正整數N,K(0<N<1000,0<K<=N),分別表示成績單上總共的學生數目,和小明的學號。
第二行有N個整數Xi(0<=Xi<=100)分別表示各個學生的成績,以學號遞增順序給出,第一個學生學號爲1。

輸出

對於每組數據,請在一行裏輸出班裏一共有多少個學生成績高於小明。

樣例輸入

1
3 2
81 72 63

樣例輸出

1

簡單思路

for歷遍一下就可以

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
    int t;
    int n,k;
    while(cin>>t){
        while(t--){
            int a[2000]={0};
            memset(a,0,sizeof(a));
            cin>>n>>k;
            for(int i=1;i<=n;i++)
                cin>>a[i];
            int t=a[k];
            int count=0;
            for(int i=1;i<=n;i++)
                if(a[i]>t)
                    count++;
            cout<<count<<endl;
        }
    }
    return 0;
}

問題 D: 【基礎題】儘可能大的三位數

題目描述

輸入一個三位數的正整數,將數字位置重新排列,組成一個儘可大的三位數。例如:輸入213,重新排列可得到儘可能大的三位數是321。

輸入

三位數的正整數。

輸出

重排後儘可能大的三位數。

樣例輸入

213

樣例輸出

321

簡單思路

sort一下就行

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
bool cmp(char a,char b){
    return a>b;
}
int main(){
    char a[10];
    while(cin>>a[0]>>a[1]>>a[2]){
        sort(a,a+3,cmp);
        cout<<a[0]<<a[1]<<a[2]<<endl;
    }
    return 0;
}

問題 E: 會場安排問題

題目描述

假設要在足夠多的會場裏安排一批活動,並希望使用儘可能少的會場。設計一個有效的
貪心算法進行安排。(這個問題實際上是著名的圖着色問題。若將每一個活動作爲圖的一個
頂點,不相容活動間用邊相連。使相鄰頂點着有不同顏色的最小着色數,相應於要找的最小
會場數。)

編程任務:

對於給定的 k 個待安排的活動,編程計算使用最少會場的時間表。

輸入

第一行有 1 個正整數 k,表示有 k 個待安排的活動。接
下來的 k 行中,每行有 2 個正整數,分別表示 k 個待安排的活動開始時間和結束時間。時間
以 0 點開始的分鐘計。

輸出

將編程計算出的最少會場數輸出

樣例輸入

5
1 23
12 28
25 35
27 80
36 50

樣例輸出

3

提示

k<10000

簡單思路

begin排序 end小了就開一個會場

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int s[11111],e[11111];
int main(){
    int n=0,i=0,j=0,k=0;
    cin>>n;
    for(;i<n;i++)
        cin>>s[i]>>e[i];
    sort(s,s+n);
    sort(e,e+n);
    for(i=0;i<n;i++) {
        if(s[i]<e[j]) k++;
        else j++;
    }
    cout<<k<<endl;
    system("pause");
    return 0;
}

問題 F: 飛翔

題目描述

鷹最驕傲的就是翱翔,但是鷹們互相都很嫉妒別的鷹比自己飛的快,更嫉妒其他的鷹比自己飛行的有技巧。於是,他們決定舉辦一場比賽,比賽的地方將在一個迷宮之中。
這些鷹的起始點被設在一個N*M矩陣的左下角map[1,1]的左下角。終點被設定在矩陣的右上角map[N,M]的右上角,有些map[i,j]是可以從中間穿越的。每一個方格的邊長都是100米。如圖所示:

沒有障礙,也沒有死路。這樣設計主要是爲了高速飛行的鷹們不要發現死路來不及調整而發生意外。潘帕斯雄鷹冒着減RP的危險從比賽承辦方戒備森嚴的基地中偷 來了施工的地圖。但是問題也隨之而來,他必須在比賽開始之前把地圖的每一條路都搞清楚,從中找到一條到達終點最近的路。(哈哈,笨鳥不先飛也要拿冠軍)但 是此鷹是前無古鷹,後無來鷹的吃菜長大的鷹–菜鳥。他自己沒有辦法得出最短的路徑,於是緊急之下找到了學OI的你,希望找到你的幫助。

輸入

首行爲n,m(0<n,m<=1000000),第2行爲k(0<k<=1000)表示有多少個特殊的邊。以下k行爲兩個數,i,j表示map[i,j]是可以直接穿越的。

輸出

僅一行,1,1–>n,m的最短路徑的長度,四捨五入保留到整數即可

樣例輸入

3 2
3
1 1
3 2
1 2

樣例輸出

383

簡單思路

找最長上升的數量 即走斜線的數量
然後就是找上升個數和長度的規律(其實一目瞭然) 4舍5入

//n,m小的話可以dfs 但是這個太大了。。。 
//其實算出上升數量就行了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
struct N{
    int x;
    int y;
};
N node[1111];
int dp[1111];
bool cmp(N a, N b){
    return a.x<b.x;
}
int main(){
    int n,m,k;
    while(cin>>n>>m>>k){
        memset(dp,0,sizeof(dp));
        for(int i=0;i<k;i++)
            cin>>node[i].x>>node[i].y;
        sort(node,node+k,cmp);
        int maxn = 0;
		for(int i=0;i<k;i++){
			dp[i]=1;
			for(int j=0;j<i;j++)
				if(node[i].x > node[j].x && node[i].y > node[j].y && dp[i] < dp[j]+1)
					dp[i] = dp[j]+1;
			if(dp[i] > maxn)
				maxn = dp[i];
        }
        double t=100.0*(n+m-2*maxn)+sqrt(2)*100.0*maxn;
        cout<<(int)(t+0.5)<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章