Codeforces Round #521 (Div. 3)
阿新 • • 發佈:2018-11-17
題目連結: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> 2using 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 elsei++; 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 }