1. 程式人生 > >2020年“感恩杯”台州學院第十三屆大學生程式設計競賽D、H、I題解(後續補充)

2020年“感恩杯”台州學院第十三屆大學生程式設計競賽D、H、I題解(後續補充)

D題:小z與他的襪子

描述

小z每天會穿一雙新襪子。

開始他的衣櫃裡有n雙襪子,襪子會從1~n進行編號。每天早上他都會從衣櫃裡拿編號最小的襪子來穿。每天晚上他會把今天穿的襪子扔進籃子裡,如果籃子裡有n-1雙襪子了,懶惰的小z就得必須把他們洗掉,明天晚上他們會重新放進衣櫃裡。

小z想知道在第k天他應該穿哪雙襪子。

輸入

輸入為1行,分別是小z的襪子數n和天數k。(2<n<103,1<k<104)

輸出

輸出為1行,為小z第k天穿的襪子編號。

樣例輸入

2 7

樣例輸出

1

思路:按題意模擬,會發現前n天 穿的襪子編號是1到n,n天之後會以2*(n-1)天迴圈穿1~(n-1)~1~(n-2)編號的襪子。

程式碼

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;

int a[N];
int main() {
    int n,k;
    cin>>n>>k;
    if(k<=n) cout<<k<<endl;
    else {
        int e = 0;
        k-=n;
        for(int i = 1;i < n;i++) {
            a[++e] = i;
        }
        for(int i = 1;i < n-1;i++) {
            a[++e] = i;
        }
        a[++e] = n;
        a[0] = a[e];
        cout<<a[k%e]<<endl;
    }
}
View Code

H題:小z的遙控車

描述

小z新買了一輛遙控車,這個遙控車的遙控器上的按鍵按一次可以

  1.前進或後退1m

  2.前進或後退7m

  3.前進或後退10m

現在他想跑x米,x>0,代表前進x米,x=0,代表原地不動,x<0,代表後退x米。小z想知道他的最小運算元。

 

輸入

資料包含多組,第一行為整數T(1≤T≤100),代表測試的組數。

下面有T組資料,每組1行,為1個整數x,即小z想跑的距離(-100<=x<=100)。

 

輸出

每組輸出一行,即小z的操作次數。

 

樣例輸入

3
8
0
-7

樣例輸出

2
0
1

題意:在一維座標上走x米,求最小操作次數。 題目給出了6種操作方式:(1.前進或後退1m。2.前進或後退7m。 3.前進或後退10m。)

題意相當於給你x米,用6種操作方式使x變成0。如何得到最小的操作次數呢,先不管。康這裡,如果能讓6種操作方式同步在x上進行,每同時進行一次,操作次數加1,每次對x操作後得到的值xx在之前的操作中沒出現過,就把xx和運算元存起來,直到某一步操作中把x變成了0,那麼對應的step就是最小操作次數。

程式碼

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;

int dx[]={-1,1,-7,7,-10,10};
map<int,bool>mp;///標記
int BFS(int x) {
    queue<pair<int,int> >qu;///pair也可以換成結構體
    qu.push({x,0});///初始化操作值 和 操作次數
    mp.clear();///map放全域性使用前記得清空
    while(qu.size()){
        x = qu.front().first;
        int step = qu.front().second;
        qu.pop();
        if(x==0) return step;
        step++;
        for(int i = 0;i < 6;i++) {
            int now = x+dx[i];
            if(!mp[now]) {
                mp[now] = true;
                qu.push({now,step});
            }
        }
    }
}
int main() {
    int T;
    cin>>T;
    int x;
    while(T--) {
        cin>>x;
        cout<<BFS(x)<<endl;
    }
}
View Code

I題:小z的班級平時分

描述

小z的美術老師還沒有把班上學生認全,於是他從班主任手上拿到了教室座位表。座位表有n行m列,上面寫著學生的姓名拼音,小z班上沒有學生重名,如果為None(不會全為None),表示當前座位沒有坐人。

開始時所有人的平時分均為0分,遲到一次扣5分,回答一次問題得3分;第x排第y列遲到了,美術老師會記錄下“1 x y”,第x排第y列回答了問題,美術老師會記下“2 x y”。 

慢慢地美術老師已經把班級同學全都認識了,但是她想知道之前分別是誰獲得最高分和最低分。

 

輸入

輸入資料包含多組,以EOF作為結束。

第一行為整數n和m,代表這個教室為n行m列(1<=n,m<=10)。

接下來n行每行為m個學生的名字,之間用空格隔開,學生名字不含空格,且不超過20個字元。

第n+2行為整數q(0<=q<=100),代表美術老師記錄的條數。

接下來q行,每行均為3個整數op,x,y,代表第x行第y列的學生遲到或回答了問題(見描述)。

 

輸出

每組輸出兩行。

第一行為得分最高的學生姓名及分數,如果分數相同,請輸出字典序較小的學生姓名,中間用空格隔開。

第二行為得分最低的學生姓名及分數,如果分數相同,請輸出字典序較小的學生姓名,中間用空格隔開。

 

樣例輸入

3 3
ChenggongZheng SanZhang SiLi
FeihongHuang BaoyuJia DaiyuLin
None BaochaiXue XifengWang
5
1 1 2
1 3 3
2 1 1
2 3 3
1 1 2

樣例輸出

ChenggongZheng 3
SanZhang -10

這裡的(1<=n,m<=10) 可以直接用二維陣列加結構體模擬位置,模擬完之後要排序,二維陣列怎麼排序呢,我也不懂,那就把二維轉成一維。排序可以用sort,可以在結構體裡過載排序函式,也可以自己寫一個排序函式放在sort的第三個引數位置。排好序後就是輸出了。如果按成績從高到底,相同成績按名字字典序從小到大(兩個字串的字典序大小:同時從第一個字元開始比較,以26英文字母順序後者比前者大排,某個位置比較出了大小就結束比較),那麼下標是0的一維陣列結構體存的資訊就是最高分及同分名字字典序最小的。找最低分且名字字典序最小,就要從排好序的數組裡從後往前遍歷,如果遍歷到下標 [ i ] 陣列存的分數資訊不等於最後一個下標存的分數資訊,就輸出下標【i+1】陣列的資訊即可。

上面羅裡吧嗦了一堆。

再加上特殊考慮最高分和最低分可能是同一個人即可。

程式碼

#include<bits/stdc++.h>
using namespace std;
const int N = 100+5;

struct node {
    string s;
    int num;
    bool operator<(const node a) {
        if(num!=a.num)
            return num>a.num;
        return s < a.s;
    }
}b[N],a[N][N];
int main() {
    int n,m;
    string s;
    while(cin>>n>>m) {
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= m;j++) {
                cin>>s;
                a[i][j] ={s,0};
            }
        }
        int T;
        cin>>T;
        int e = -1;
        int id,x,y;
        while(T--) {
            cin>>id>>x>>y;
            if(id==1) a[x][y].num-=5;
            else if(id==2) a[x][y].num+=3;
        }
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= m;j++) {
                if(a[i][j].s!="None")
                    b[++e] = a[i][j];
            }
        }
        sort(b,b+e+1);
        cout<<b[0].s<<' '<<b[0].num<<endl;
        for(int i = e;i>=0;i--) {
            if(i==0||b[e].num!=b[i].num) {
                if(b[e].num!=b[i].num) i++;
                cout<<b[i].s<<' '<<b[i].num<<endl;
                break;
            }
        }

    }
}
View Code

&n