1. 程式人生 > >Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round)

Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round)

機器 mar 數據 .org 多個 n) height lap 不同的

A. Technogoblet of Fire

題意:n個人分別屬於m個不同的學校 每個學校的最強者能夠選中 黑客要使 k個他選中的可以穩被選 所以就為這k個人偽造學校 問最小需要偽造多少個

思路:記錄每個學校都有哪些人 每次看黑客選中的人是不是在學校是最強者(這裏要處理能力一樣的情況,如果有能力一樣的為了保證穩進也要偽造一個學校) 然後就是模擬了

技術分享圖片
 1 #include<bits/stdc++.h>
 2 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
 3 #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
 4
#define F first 5 #define S second 6 #define pii pair<int ,int > 7 #define mkp make_pair 8 #define pb push_back 9 using namespace std; 10 const int maxn=500+5; 11 vector<pii>v[maxn]; 12 int p[maxn],s[maxn]; 13 14 int main(){ 15 int n,m,k; 16 scanf("%d%d%d",&n,&m,&k);
17 FOR(i,1,n)scanf("%d",&p[i]); 18 FOR(i,1,n){ 19 scanf("%d",&s[i]); 20 v[s[i]].pb(mkp(p[i],i)); 21 } 22 int cnt=0; 23 int id; 24 FOR(i,0,k-1){ 25 scanf("%d",&id); 26 for(int j=0;j<v[s[id]].size();j++){ 27 if(v[s[id]][j].F>=p[id]&&v[s[id]][j].S!=id){
28 cnt++; 29 break; 30 } 31 } 32 for(int j=0;j<v[s[id]].size();j++){ 33 if(v[s[id]][j]==mkp(p[id],s[id])){ 34 v[s[id]].erase(v[s[id]].begin()+j); 35 break; 36 } 37 } 38 } 39 cout<<cnt<<endl; 40 return 0; 41 }
View Code B. Mike and Children 題意:給出N個數 每個數都不一樣 兩兩組合 問使組合後的和相等的 最大對數是幾 思路:因為每個數字都不一樣 直接暴力枚舉每個可能的值即可 技術分享圖片
 1 #include<bits/stdc++.h>
 2 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
 3 #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
 4 #define F first 
 5 #define S second
 6 #define pii pair<int ,int >
 7 #define mkp make_pair
 8 #define pb push_back
 9 using namespace std;
10 const int maxn=5000+5;
11 vector<pii>v[maxn];
12 int a[maxn],s[maxn];
13 set<int>q;
14 map<int,int>mp;
15 int main(){
16     int n;
17     scanf("%d",&n);
18     FOR(i,0,n-1){scanf("%d",&a[i]);}
19     int cnt=0;
20     int id=0;
21     FOR(i,0,n-1){
22         FOR(j,i+1,n-1){
23             q.insert(a[i]+a[j]);
24             mp[a[i]+a[j]]++;
25                 if(cnt<mp[a[i]+a[j]]){
26                     cnt=mp[a[i]+a[j]];
27                     id=a[i]+a[j];
28                 }
29         }
30     }
31     
32     cout<<cnt<<endl;
33 }
View Code

C. System Testing

題意:一秒測試一個樣例 一共有m臺機器和n個題目 給出每個題目的樣例數 問存在多少個round(100*ok/n) ==當前測試到的樣例數 ok是已經完成的題數

思路:這裏剛開始寫的時候是用優先隊列模擬的,會出現一個bug 因為是並行計算的,所以當前最先完成測試的題目 測試到的樣例 滿足round(100*ok/n)==樣例數 可能會出現在上上個題目之前(包含上上個) 這樣就會統計不到

所以還是離散化秒數 用秒模擬即可(這題的數據範圍是允許的) 參考了超哥的代碼

技術分享圖片
 1 #include<bits/stdc++.h>
 2 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
 3 #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
 4 #define F first 
 5 #define S second
 6 #define pii pair<int ,int >
 7 #define mkp make_pair
 8 #define pb push_back
 9 using namespace std;
10 const int maxn=1000+5;
11 int vis[maxn],mk[maxn],p[maxn],a[maxn];
12 int ans=0;
13 double ti=0.5;
14 int main(){
15     int n,k,m;
16     scanf("%d%d",&n,&k);
17     m=0;
18     int tmp;
19     FOR(i,1,n){
20         scanf("%d",&a[i]);
21     }
22     k=min(n,k);
23     FOR(i,1,k)vis[i]=1;
24     for(;;ti+=1){
25         for(int i=1;i<=n;i++){
26             if(vis[i]==1)p[i]++;
27         }
28 
29     int d=round(100.0*m/n);
30 
31         for(int i=1;i<=n;i++){
32             if(vis[i]==1&&p[i]==d&&!mk[i]){ans++;mk[i]=1;}
33         }
34         
35         for(int i=1;i<=n;i++){
36             if(p[i]==a[i]&&vis[i]==1){
37                 m++;
38                 vis[i]=-1;
39                 for(int j=i+1;j<=n;j++){
40                     if(!vis[j]){vis[j]=1;break;}
41                 }
42             }
43         }
44         if(m==n)break;
45     }
46     cout<<ans<<endl;
47 return 0;
48 }
View Code

F. Compress String

把一個字符串包裝成很多個連續的部分 單個字符串需要消耗a 如果 tl tl+1 ...tr是前面t1...tl-1的子序列只需要消耗b問最小代價

思路:維護一個最長公共子串詳細見代碼

 1 #include<bits/stdc++.h>
 2 #define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
 3 #define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
 4 #define F first 
 5 #define S second
 6 #define pii pair<int ,int >
 7 #define mkp make_pair
 8 #define pb push_back
 9 using namespace std;
10 const int maxn=5000+5;
11 int dp[maxn];
12 int lcs[maxn][maxn];
13 char s[maxn];
14 int main(){
15     int n,a,b;
16     scanf("%d%d%d",&n,&a,&b);
17     scanf("%s",s+1);
18     FOR(i,1,n){
19         dp[i]=dp[i-1]+a;//初始化刪一個
20         FOR(j,1,i-1){
21         if(s[i]==s[j])lcs[i][j]=lcs[i-1][j-1]+1;// 維護前i個和前j的最長公共子串並且終點是在i的
22         if(lcs[i][j]!=0&&i-j>=lcs[i][j])dp[i]=min(dp[i],dp[i-lcs[i][j]]+b);//如果1-i,1-j存在公共子串其中一個終點在i並且大區間(也就是終點的i)的起點在小區間的前面 即可更新dp[i][j] 可畫圖理解其正確性
23         }
24     }
25     cout<<dp[n]<<endl;
26     return 0;
27 }

??=

??????????(100????)

Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round)