1. 程式人生 > >長沙理工大學ACMore程式設計協會2018年新生賽(重現賽)

長沙理工大學ACMore程式設計協會2018年新生賽(重現賽)

A 送氣球.jpg
連結:https://ac.nowcoder.com/acm/contest/318/A
來源:牛客網

題目描述
ACM-ICPC程式設計大賽是大學級別最高的腦力競賽,素來被冠以"程式設計的奧林匹克"的尊稱。大賽至今已有近40年的歷史,是世界範圍內歷史最悠久、規模最大的程式設計競賽。比賽形式是:從各大洲區域預賽出線的參賽隊伍,於指定的時間、地點參加世界級的決賽,由1個教練、3個成員組成的小組應用一臺計算機解決7到13個生活中的實際問題。在正式賽場中,一個隊伍每解決一個新的問題就會有一個相應的氣球作為獎勵送到這個隊伍所在的位置。
Dillonh作為這次ACM-ICPC的志願者,當然是時刻關注著場上的過題情況的,每當有一個隊伍通過新的問題的時候,他就會馬上送上氣球。但由於參賽隊伍實在是太多了,他也不清楚每個隊伍得到了多少個氣球。在比賽結束之後,他拿到了一份這場比賽的題目提交情況,他想知道現場參加比賽的隊伍每個隊伍能獲得氣球,聰明的你能幫幫他嗎?

輸入描述:
第一行包含一個整數T(T≤10),表示總共有T組測試樣例;
第二行輸入一個整數n,m;
n表示有多少個隊伍參加這次的比賽(1≤n≤50);
m表示有多少條提交記錄(1≤m≤1000);
接下來輸入m行,每行輸入格式如下:
team_id problem_id submit_status
team_id 代表著隊伍的編號(1 <= team_id <= n);problem_id代表著題目編號(為A~M的大寫字母);submit_status代表著這個題目提交的結果(可能是"AC",“PE”,“TLE”,“MLE”,“WA”,“RE”,"CE"其中的一種)。
hint:每次提交只有提交結果是"AC"的題目才可以得到氣球。如果一個隊伍如果通過同一個題目多次,他也只能獲得一個氣球。
輸出描述:
對於每組樣例
第一行輸出一行“Case #x:”,x表示當前為第幾組樣例(詳細見樣例);
第二行輸出n個數(每兩個數之間用空格隔開)代表著第 i 個隊可以獲得的氣球數量。(注意不要在每一行的末尾輸出多餘的空格)。
示例1
輸入

1
5 10
1 A WA
1 A AC
2 A AC
3 C TLE
2 C TLE
1 C AC
3 A AC
4 A AC
1 A AC
5 A WA

輸出

Case #1:
2 1 1 1 0

照著模擬就行,set去重。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000;
set<char>s[maxn];
int main(){
	int t;
	cin>>t;
	int flag=1;
	while(t--){
		int n,m;
		cin>>n>>m;
		
		for(int i=0;i<m;i++){
			int index;
			char b;
			string c;
			cin>>index>>b>>c;
			if(c=="AC"){
				s[index].insert(b);
			}
		}
		printf("Case #%d:\n",flag);
		
		for(int i=1;i<n;i++){
			cout<<s[i].size()<<" ";
			s[i].clear();
		}
		cout<<s[n].size()<<endl;
		s[n].clear();
		flag++;
	}
	
}

B 簽到題
連結:https://ac.nowcoder.com/acm/contest/318/B
來源:牛客網

題目描述
IG牛逼!!!

眾所周知,IG是英雄聯盟S8世界總決賽冠軍,奪冠之夜,數億人為之歡呼!

賽後某百分百勝率退役ADC選手的某表情包意外走紅,某苟會長看到此表情包也想模仿。

於是有n個友愛的萌新決定每人都送會長一根長為ai麵包。(資料保證沒有面包的長度相等)

會長無聊時把麵包擺成一排,他驚人地發現他喜歡這樣一類區間,區間[i, j]滿足條件:

區間裡的麵包沒有比左端點i號麵包短的,同時也沒有比右端點j號麵包長的。

Gey會長在思考這樣一個問題:

所有滿足條件的區間中j-i的最大值是多少?

輸入描述:

t組資料。
每組樣例第一行輸入整數n,接下來一行輸入n個正整數。
(t≤30, n≤1000, ai≤1000000)

輸出描述:

輸出滿足條件的區間中j-i的最大值。

示例1
輸入

2
4
5 4 3 6
4
6 5 4 3

輸出

1
0

暴力,雙重遍歷確定起點和終點,終點為這一區間最大值時更新區間長度。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
int a[maxn];
int main(){
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int ans=0;
        for(int i=1;i<n;i++)
        {
            int mx=a[i];
            for(int j=i+1;j<=n;j++)
            {
                if(a[j]<a[i]) break;
                mx=max(mx,a[j]);
                if(mx==a[j])
                    ans=max(ans,j-i);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

G LLLYYY的數字思維
連結:https://ac.nowcoder.com/acm/contest/318/G
來源:牛客網

題目描述
LLLYYY很喜歡寫暴力模擬貪心思維。某一天在機房,他突然拋給了隊友ppq一
個問題。問題如下:
有一個函式f ():
int f(int x){
int tmp = 0;
while(x != 0){
tmp += x % 10;
x /= 10;
}
return tmp;
}
接著LLLYYY給定一個整數 c,要求在c範圍內找兩個整數a和b,使得a + b = c,且f(a) + f(b)的值最大。
輸入描述:

採用多組輸入方式。
每行輸入一個整數 c (1≤c≤1012)。

輸出描述:

對於每一個 c,找到一組 a,b ,使 f(a) + f(b)最大 且 a + b = c,輸出這個f(a) + f(b)(0≤a,b≤c)。

示例1
輸入

35
10000000000

輸出

17
91

說明

在第一個樣例中,可以選擇 a = 17,b = 18,這樣得到的f(a) + f(b)值最大為 17。
在第二個樣例中, 可以選擇 a = 5000000001,b = 4999999999.這樣得到的f(a) + f(b)值最大為 91。

不要看說明,會被誤導。數肯定是9越多越好

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int f(ll x){
    int tmp = 0;
    while(x != 0){
    tmp += x % 10;
    x /= 10;
    }
    return tmp;
}
int main(){
    ll c,n;
    while(cin>>c){
        n=0;int s=0;
        while((n*10+9)<c) n=n*10+9;
        printf("%d\n",f(n)+f(c-n));
    }
    return 0;
}

J 王者榮耀
連結:https://ac.nowcoder.com/acm/contest/318/J
來源:牛客網

題目描述
“無論何時何地,都會遵守約定”。“奮力逃吧”。“關於取下敵人性命這件事,也從不失約”。

小懶蟲zmx平時最喜歡玩的遊戲就是《王者榮耀》,在這款遊戲中它也最喜歡百里守約這個英雄。最近,zmx準備衝國服百里,所以它開始練英雄,你有很多個時間段來練習英雄,每個時間段有一個開始時間點和結束時間點,以及可以獲得的熟練度。不過現在你可以隨意修改任意練習時間段的開始和結束時間點,但是你不能修改時間段的長度和獲得的熟練度!由於要學習,你只能在固定時間段玩遊戲,問你最多可以獲得多少熟練度?

例如:你可以把[2,3),修改為[1,2)或者[3,4)等等,他們的長度都是1。

注意:對於某個時間段,不管你有沒有修改,必須練完整個時間段長度才能獲得熟練度!

輸入描述:

第一行,三個整數n,S,T(0<n<=1000,0<S<T<1000)代表n個時間段和你能在[S,T)時間段內玩遊戲。

接下來n行,每行三個整數a,b(0<a<b<1000),c(0<c<1e7),用空格分開,代表時間段起始時間[a,b)和可以獲得的熟練度。

輸出描述:

輸出一行,包括一個整數,表示zmx能獲得的最大熟練度。

示例1
輸入

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

輸出

6

示例2
輸入

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

輸出

7

以時間間隔作為揹包容量,看能裝多少東西。
每段時間間隔作為消耗,經驗作為價值。揹包問題。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2000;
int n;
long long f[maxn];
int main(){
    int s,t,v;
    scanf("%d%d%d",&n,&s,&t);
    v=t-s;
    for(int i=1;i<=n;++i) {
        int w;
        scanf("%d%d%d",&s,&t,&w);
        int c=t-s;
        for(int j=v;j>=c;j--) {
            f[j]=max(f[j],f[j-c]+w);
        }
    }
  
    cout<<f[v]<<endl;
    return 0;
}

L 彪神666
連結:https://ac.nowcoder.com/acm/contest/318/L
來源:牛客網

題目描述
在國外,666代表魔鬼,777代表上帝。

所以牛逼的彪神就非常不喜歡6這個數字。

有一天彪神突發奇想,,他想求一些書與6無關的數。

如果一個數能被6整除,或者它的十進位制表示法中某位上的數字為6,則稱其為與6相關的數。彪神要求所有小於等於N的與6無關的正整數的平方和。

輸入描述:

第一行一個數T表示有T組資料。(T≤20)

後面T行數每行一個N,表示求所有小於等於N的與6無關的正整數的平方和。(N≤106)

輸出描述:

T行,每行一個數表示求所有小於等於N的與6無關的正整數的平方和。

示例1
輸入

5
4
5
6
7
8

輸出

30
55
55
104
168

暴力

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll calculate(ll num){
    if(num%6==0)
        return 0;
    ll x=num;
    while(x){
        if(x%10==6)
            return 0;
        x/=10;
    }
    return num*num;
}
ll ans;
int n,t;
int main()
{
    cin>>t;
    while(t--){
        cin>>n;
        for(ll i=1;i<=n;++i)
            ans+=calculate(i);
        cout<<ans<<endl;
        ans=0;
    }
    return 0;
}

M 被打臉的瀟灑哥
連結:https://ac.nowcoder.com/acm/contest/318/M
來源:牛客網

題目描述
“畫個圈圈詛咒你!”
在一次青青草原ACM個人賽中,瀟灑哥被喜洋洋以30s罰時壓制,委屈的當了個第二。瀟灑哥蹲在角落說出了他的口頭禪,並畫起了圈圈。
突然,他想出了一個有趣的題目,跑去給喜洋洋做。喜洋洋看到題目後懵逼了,但是看到瀟灑哥臉上欠揍的笑容就不爽,暗想一定要做出來狠狠的打瀟灑哥的臉。
於是,他以上廁所為名義跑出來用手機把題目發給了你,希望你能幫你做出來讓他可以嘲諷瀟灑哥。
你收到的題目如下:
平面上有n個圓,求使這n個圓兩兩相交(即每兩個圓之間恰好有兩個交點)後最多能把平面劃分成多少個區域。

輸入描述:

一個正整數t,表示有t(1≤t≤100)組資料。
接下來t行,每行一個整數n(0≤n≤1000),代表平面內圓的個數。

輸出描述:

輸出共t行。每行一個正整數,表示對應的n個圓將該平面劃分成的最大的區域數。

示例1
輸入

3
1
2
3

輸出

2
4
8

說明

第一個樣例,平面只有一個圓,此時將平面劃分成圓內和圓外兩個區域;
第二個樣例,平面上有兩個圓,兩圓相交可以將平面劃分成四個區域(見下圖)。

一個圓最多能把平面分成2個部分,
2個圓最多能把平面分成4個部分;
3個圓最多能把平面分成8個部分;
現在加入第4個圓,為了使分成的部分最多,第4個圓必須與前面3個圓都有兩個交點;

因此得6個交點將第4個圓的圓周分成6段圓弧,而每一段圓弧將原來的部分一分為二,即增加了一個部分,於是4個圓最多將平面分成8+6=14個部分,
同理,5個圓最多將平面分成14+8=22個部分,
一般地,n個圓最多分平面為:
2+1×2+2×2+…+(n-1)×2,
=2+2[1+2+…+(n-1)],
=n2-n+2;
當n=10時,最多可以分成:102-10+2=92(部分),
答:10個圓最多可以把平面分成92部分.
故答案為:92.

這題注意特判0的情況

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	int t;
	cin>>t;
	while(t--){
		ll n;
		cin>>n;
	    ll sum=n*n-n+2;
	    
	    cout<<sum<<endl;
	}
}