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\n";
        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\n";
        }
        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;
}

原文地址:https://www.cnblogs.com/163467wyj/p/11939346.html

时间: 2024-11-08 21:33:00

Comet OJ - Contest #15题解的相关文章

Comet OJ - Contest #15

https://cometoj.com/contest/79/problem/D?problem_id=4219 题目描述 ※ 简单版与困难版的唯一区别是粗体字部份和 $v$ 的数据范围. 在双 11 时,心慧精品店有个特别的折价活动如下: 首先,我们定义一个正整数为"好的"当且仅当此数仅由数字 1 构成,举例来说 1, 11, 111, 11111 都是「好的」,但 10.123.321 都是「不好的」. 接着,若一个商品原价为 x,若顾客能把 x 表示为 k 个「好的」数字,那么此

Comet OJ - Contest #8题解

传送门 \(A\) 咕咕咕 const int N=1005; char s[N][N];int len[N],n,id; inline bool cmp(R int j,R int k){ R int l=min(len[j],len[k]); fp(i,1,l)if(s[j][i]!=s[k][i])return s[j][i]<s[k][i]; return len[j]<len[k]; } int main(){ scanf("%d",&n),id=1; f

Comet OJ - Contest #14题解

Contest14的本质:区间覆盖+Tarjan( A 把距离公式两边平方即可 注意要long long code #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #define fo(a,b,c) for (a=b; a<=c; a++) #define fd(a,b,c) for (a=b;

Comet OJ - Contest #5

Comet OJ - Contest #5 总有一天,我会拿掉给\(dyj\)的小裙子的. A 显然 \(ans = min(cnt_1/3,cnt_4/2,cnt5)\) B 我们可以感性理解一下,最大的满足条件的\(x\)不会太大 因为当\(x\)越来越大时\(f(x)\)的增长速度比\(x\)的增长速度慢得多 其实可以证明,最大的满足的\(x\)不会超过\(100\) 因为没有任何一个三位数的各位之和大于等于\(50\) 所以我们就直接预处理\(1-99\)所有的合法的 暴力枚举即可 其实

符文能量(Comet OJ - Contest #8)

给Comet OJ打个小广告,挺好用的,比较简洁,给人感觉很好用 Contest #8是我打的第一场本oj比赛,很遗憾A了前两道傻逼题就没思路了,然后就不打算打了....... https://www.cometoj.com/contest/58/problem/C?problem_id=2760 怎么做啊完全不会啊我那么菜,虽然看到是dp但嫌太麻烦就放弃了: 靠后仔细想了想原来这道题很简单: 结构体node e[];储存ai,bi值(当然你用数组我也不拦着),因为合并的方式很特殊,可以不管合并

Comet OJ - Contest #10 B

Comet OJ - Contest #10 B 沉鱼落雁 思维题 题意 : 每个数字最多重复出现三次,有n给数字,让你尽可能的使得相同数字之间的最小距离尽可能大 思路 :分三种情况套路 设 a b c 分别代表出现 一次, 两次, 三次 数字的个数 所有元素至多出现一次,答案为 n,题目规定 所有元素至多出现两次, 例如 1 1 2,可以排列成 1 2 1,所以,答案为 1 例如 1 1 2 2 3,可以排列成 1 2 3 1 2,所有 答案为 2 思考后得出,应该尽可能的把 b 个出现两次的

Comet OJ - Contest #9 &amp; X Round 3题解

传送门 \(A\) 咕咕 typedef long long ll; int a1,a2,n,d;ll res; int main(){ scanf("%d%d%d",&a1,&a2,&n); d=a2-a1; res=1ll*(a1+a1+1ll*(n-1)*d)*n>>1; printf("%lld\n",res); return 0; } \(B\) 不难发现答案要么是\(1\)要么是\(2\) 当且仅当\(k+1\)是个质

Comet OJ - Contest #13 补题题解

A.险恶的迷宫 题意:在二维平面坐标内,给出一个圆心坐标 (a,b),以及圆的半径 r , 再给出 n 个点的坐标 (x_i,y_i),  求有多少点在圆内. 数据范围:0  <  n  <= 1e5,      0< r , x , y  <=1e9 思路:对于判断距离根据勾股定理: sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) <= r ,即在圆的范围内.由于此题数据较大,sqrt可能导致精度损失,所以直接开long long 进行平方比较

Comet OJ - Contest #7 解题报告

传送门:https://www.cometoj.com/contest/52 A:签到题 题意:多次询问,每次询问给出一个值域区间[l,r],从这区间范围中选出两个整数(可重复),依次求出这俩数的“最大的最小公倍数”.“最小的最小公倍数”.“最大的最大公约数”.最小的最大公约数. 分析:(1)显然,当区间长度为1时,该问题的答案只能是区间中仅有的那个数. (2)当区间的长度大于1时,最大的最小公倍数,lcmmax =lcm(ar,ar-1) = ar * ar-1: 最小的最小公倍数,lcmmi