Comet OJ - Contest #15题解
Posted 163467wyj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Comet OJ - Contest #15题解相关的知识,希望对你有一定的参考价值。
A 双十一特惠 (简单版)
n <= 1e19, 1e9 > 1(8)
https://www.cometoj.com/contest/79/problem/A?problem_id=4198
#include<bits/stdc++.h> using namespace std; int main(){ int t; cin >> t; while(t--) { int cnt1 = 0; int n;cin >> n; int pr[] = {1,11,111,1111,11111,111111,1111111,11111111,111111111}; for(int i = 8; i >= 0; i--) { cnt1 += n/pr[i]; n %= pr[i]; } if(cnt1 > 9) cout << "Impossible "; else cout << cnt1 << endl; } return 0; }
D 困难版
https://www.cometoj.com/contest/79/analysis // dm聚聚在线讲题, 走过路过不要错过
可以假设一个 特殊的进制, 1 11 111 1111 …………
然后将十进制数转为这个进制, 比如说 234 -> 2,1,1(2*111+1*11+1)
该进制下的位数相加为所需要的 “好的数” 的数量, 我们会发现当除了最后一位其他位数 大于9时, 可以转化为更小的该进制
比如说 11,0,0 -> 1,0,10,0 10,0,1,0 ->1,0,0,0,10
然后我们可以将第i个进制为i , 取该进制下的贡献
11,0,0 -> 1,0,10,0(11*3=33 1*4+10*1=14) 10,0,1,0 ->1,0,0,0,10 (10*4+2=42 1*5+10=15)
会发现当有位数大于9时(非末位)转化为更小的进制 贡献更小, 所以我们可以一直将他转化为更小的 故符合贪心选择性质
结论: 将一个十进制数用“好的数”表示时, 尽可能用当前满足的最大的“好的数”表示, 所耗费的“好的数”数量最少
B 当我们同心在一起
https://www.cometoj.com/contest/79/problem/B?problem_id=4199
#include<bits/stdc++.h> #define ll long long //暴力枚举每个坐标作为圆心的情况下 能有几个距离圆心距离相等的点,ans += f[cnt1] //将每个点作为圆心 其他点到圆心的距离作为数组 sort 再求有几个, 浮点数精度会有误差 所以把距离函数改成 ll 不取平方根就可以ac
//也可以将每次得到的距离用 map存,
using namespace std; ll dist(ll x1, ll y1, ll x2, ll y2){ return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int main(){ int t; t = 1; //cin >> t; while(t--) { int n;cin >> n; int ans = 0; //vector<pair<int, int> > dot(n+1); ll dx[2020], dy[2020]; for(int i = 0; i < n; i++) cin >> dx[i] >> dy[i]; for(int i = 0; i < n; i++) { int x = i; vector<ll> dis; for(int j = 0; j < n; j++){ if(i == j) continue; ll distan = dist(dx[i], dy[i], dx[j], dy[j]); dis.push_back(distan); //cout << "i = " << i << " dis = " << distan << endl << endl; } sort(dis.begin(), dis.end()); ll y = -1; int cnt1 = 1; for(int j = 0; j < n-1; j++){ //cout << dis[j] << " y = " << y << " cnt1 = " << cnt1 << endl << endl; if(dis[j] == y) cnt1++; else { ans += (cnt1*(cnt1-1)*(cnt1-2)/6); y = dis[j]; cnt1 = 1; } } //cout << "ans = " << ans << " cnt1= "<< cnt1<< " f[cnt1]" << f[cnt1] << endl << endl; ans += (cnt1*(cnt1-1)*(cnt1-2)/6); //cout << "!111 "; } cout << ans << endl; } return 0; }
#include<bits/stdc++.h> #define ll long long //看了题解, 稍微优化了下 using namespace std; ll dist(ll x1, ll y1, ll x2, ll y2){return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));} int main(){ int t; t = 1; while(t--) { int n;cin >> n; int ans = 0; //vector<pair<int, int> > dot(n+1); ll dx[2020], dy[2020]; for(int i = 0; i < n; i++) cin >> dx[i] >> dy[i]; for(int i = 0; i < n; i++) { vector<ll> dis; for(int j = 0; j < n; j++){ dis.push_back(dist(dx[i], dy[i], dx[j], dy[j])); } sort(dis.begin(), dis.end()); for(int j = 0, k; j < n; j = k){ for(k = j; dis[k] == dis[j]; k++); ans += (k-j)*(k-j-1)*(k-j-2)/6; } } cout << ans << endl; } return 0; }
以上是关于Comet OJ - Contest #15题解的主要内容,如果未能解决你的问题,请参考以下文章
Comet OJ - Contest #11 题解&赛后总结