1. 程式人生 > >Codeforces Round #521 (Div. 3)

Codeforces Round #521 (Div. 3)

題目連結:http://codeforces.com/contest/1077

A.Frog Jumping

解題思路:作差再判斷最後是否還需再一次向右跳即可。

AC程式碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 LL T,a,b,k;
 5 int main(){
 6     while(cin>>T){
 7         while(T--){
 8             cin>>a>>b>>k;
9 cout<<(a-b)*(k/2)+(k%2?a:0)<<endl; 10 } 11 } 12 return 0; 13 }
B.Disturbed People

解題思路:題意已說得很清楚了,只要找到滿足a[i-1]==1&&a[i]==0&&a[i+1]==1,那麼就關掉第i-1和第i+1間房間的燈(其狀態值改為0),若滿足條件--->i+=3,表示當前的燈已熄滅,只需站到第i+3間房間繼續查詢即可。

AC程式碼:

 1 #include<bits/stdc++.h>
 2
using namespace std; 3 typedef long long LL; 4 int n,cnt,a[105]; 5 int main(){ 6 while(cin>>n){ 7 cnt=0; 8 for(int i=0;i<n;++i)cin>>a[i]; 9 for(int i=1;i<n-1;){ 10 if(a[i-1]&&!a[i]&&a[i+1])cnt++,i+=3; 11 else
i++; 12 } 13 cout<<cnt<<endl; 14 } 15 return 0; 16 }
C.Good Array

解題思路:統計所有元素之和:sum,然後列舉每個元素,令tmp=(sum-a[i])>>1表示除去a[i]後剩餘元素之和的一半,由"好的陣列"定義可知,如果(sum-a[i])為奇數,則剩下的元素肯定不能分成相等的兩部分;否則只需檢視tmp是否在剩下的元素當中,若是則歸納答案!

AC程式碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn=2e5+5;
 5 int n,k,b[maxn];LL a[maxn],sum,tmp;map<LL,int> mp;
 6 int main(){
 7     while(~scanf("%d",&n)){
 8         sum=0,k=0;mp.clear();
 9         for(int i=1;i<=n;++i)scanf("%lld",&a[i]),sum+=a[i],mp[a[i]]++;///要用map或一維陣列記錄每個數字出現的次數,不能用set容器
10         for(int i=1;i<=n;++i){
11             if((sum-a[i])&1LL)continue;///奇數則跳過
12             tmp=(sum-a[i])>>1;
13             mp[a[i]]--;///先刪去該元素
14             if(mp[tmp])b[k++]=i;
15             mp[a[i]]++;///再新增該元素
16         }
17         printf("%d\n",k);
18         if(!k)puts("");
19         for(int i=0;i<k;++i)printf("%d%c",b[i],(i==k-1)?'\n':' ');
20     }
21     return 0;
22 }
D.Cutting Out

解題思路:

AC程式碼:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <map>
 4 #include <vector>
 5 using namespace std;
 6 typedef long long LL;
 7 int n, k, x, l, r, mid, t;
 8 map<int, int> mp;
 9 vector<int> ans, cnt;
10 bool check(int z){
11     int sum = 0;
12     for (auto num : cnt)sum += num / z;
13     return sum >= k;
14 }
15 int main(){
16     while (~scanf("%d%d", &n, &k)){
17         mp.clear(), ans.clear(), cnt.clear(); l = 1, r = n;
18         for (int i = 0; i < n; ++i)scanf("%d", &x), mp[x]++;
19         for (auto y : mp)cnt.push_back(y.second);///儲存對應數字出現的次數
20         while (l <= r){///二分查詢要切的最大次數
21             mid = (l + r) >> 1;
22             if (check(mid))l = mid + 1;///最大化往右邊找
23             else r = mid - 1;
24         }
25         for (auto u : mp){
26             t = u.second / r;
27             while (t--)ans.push_back(u.first);///第i個元素一次需要取t個
28         }
29         for (int i = 0; i < k; ++i)printf("%d%c", ans[i], i == k - 1 ? '\n' : ' ');
30     }
31     return 0;
32 }