Codeforces Round #478 (Div. 2)

30 篇文章 0 订阅
25 篇文章 0 订阅

五一放假开学前的最后一场cf,上午的新大月赛感觉还可以,但愿晚上能找到点感觉

A. Aramic script

思路:这题一看就是个字符串处理的水题,思路很清晰,但确实不是那么容易上手写

先读取,然后扔进set排序去重,最后统计,说起了感觉贼容易,写起来海星

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <set>


using namespace std;

const int maxn = 1e5+10;

map<string,bool> in;

int main()
{
    int n;
    ios::sync_with_stdio(false);
    cin >> n;
    int num = 0;
    in.clear();
    while(n--)
    {
        string s;
        cin >> s;
        int len = s.size();
        set<char> con;
        for(int i=0;i<len;i++)
        {
            con.insert(s[i]);
        }
        string now;
        set<char> :: iterator it;
        for(it = con.begin();it!=con.end();it++)
        {
            now += (*it);
        }
        if(!in[now])
        {
            in[now] = true;
            num++;
        }
    }
    cout << num << endl;
    return 0;
}

B. Mancala

思路:放置炮弹游戏,由于只有14个弹口,果断暴力,注意一下开个long long就没什么问题了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1e5+10;

long long a[14];
long long aa[14];

int main()
{
    long long score = 0LL;
    for(int i=0;i<14;i++)
    {
        scanf("%I64d",&a[i]);
        aa[i] = a[i];
        if(a[i]%2LL==0LL)
        {
            score += a[i];
            //cout << score << "*"  << endl;
        }
    }
    for(int i=0;i<14;i++)
    {
        for(int j=0;j<14;j++)
        {
            a[j] = aa[j];
        }
        long long nowscore = 0LL;
        long long num = a[i];
        a[i] = 0LL;
        long long base = num/14LL;
        num %= 14LL;
        int pos = (i+1)%14;
        while(num)
        {
            a[pos]++;
            num--;
            pos = (pos+1)%14;
        }
        for(int j=0;j<14;j++)
        {
            if((a[j]+base)%2LL==0LL)
            {
                nowscore += a[j] + base;
            }
        }
        if(nowscore > score)
        {
            score = nowscore;
            //cout << i << "*" << nowscore << endl;
        }
        /*if(i==9)
        {
            for(int j=0;j<14;j++)
            {
                cout << a[j] << "*";
            }
        }*/
    }
    printf("%I64d\n",score);
    return 0;
}

C. Valhalla Siege

思路:这题又是一个模拟,最好的方法就是预处理前缀和,过程中处理累和,扔进去二分查找一下即可定位,定位得到最终结果

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 2e5+10;

long long a[maxn],ata[maxn];

int main()
{
    int n,q;
    //freopen("in.txt","r",stdin);
    //while(scanf("%d%d",&n,&q)!=EOF)
    //{
    scanf("%d%d",&n,&q);
    scanf("%I64d",&a[0]);
    ata[0] = a[0];
    for(int i=1;i<n;i++)
    {
        scanf("%I64d",&a[i]);
        ata[i] = ata[i-1] + a[i];
    }
    long long att = 0LL;
    for(int i=0;i<q;i++)
    {
        long long k;
        scanf("%I64d",&k);
        att += k;
        int pos = upper_bound(ata,ata+n,att) - ata;
        //cout << pos << "*" <<att<< endl;
        if(pos == n)
        {
            pos = 0;
            att = 0LL;
        }
        printf("%d\n",n-pos);
   // }
    }
    return 0;
}

D. Ghosts

思路:这题确实不好做,一开始盯着望了近半小时毫无思路一开始想的是二维坐标可以做成计算几何,然而猛然发现这是个包括时间轴的三维坐标,于是事情似乎就不那么好处理了

其实,不难发现,一直都没能用上初始点在同一直线上这个结论,在这种没办法进一步进展的情况下,不妨随便写写,也比干坐着盯着看要好,说不定就水落石出了呢

于是

Xi = Xi0 + Vxi * T;
Yi = Yi0 + Vyi * T;
Xj = Xj0 + Vxj * T;
Yj = Yj0 + Vyi * T;
Yi0 = a * Xi0 + b;
Yj0 = a * Xj0 + b;


Xi = Xj
=>
Xi0 + Vxi * T = Xj0 + Vxj * T;
=>
T = (Xj0 - Xi0) / (Vxi - Vxj);


Yi = Yj
=>
Yi0 + Vyi * T = Yj0 + Vyi * T;
=>
T = (Yj0 - Yi0) / (Vyi - Vyj);
=>
T = a * (Xj0 - Xi0) / (Vyi - Vyj);
=>
(Xj0 - Xi0) / (Vxi - Vxj) = a * (Xj0 - Xi0) / (Vyi - Vyj);
=>
a *(Vxi - Vxj) =  (Vyi - Vyj);
=>

a * Vxi - Vyi = a * Vxj - Vyj;

好吧,每个点碰撞的集合居然只与a,vx,vy有关,发现的那一刻简直不敢相信

但兴奋之余不可大意,这一对计算牵扯到了除法,就必须单独处理特殊值,那就是vx不可相等,显然,由此可知vx想等的情况可以直接排除,因为当vx相等时,等式不可能成立,于是统计a*vx-vy的数量并减去相同vx的情况,再处理一下就好了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>

using namespace std;

const int maxn = 1e5+10;

typedef long long ll;

map<ll,ll> col;
map<ll,map<ll,ll> > same;

int main()
{
    ll n,a,b;
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    while(cin >> n >> a >> b)
    {
        col.clear();
        same.clear();
        while(n--)
        {
            ll x,vx,vy;
            cin >> x >> vx >> vy;
            ll temp = a * vx - vy;
            col[temp] ++;
            same[temp][vx]++;
        }
        map <ll,ll> :: iterator it,it2;
        ll re = 0LL;
        for(it = col.begin();it != col.end();it++)
        {
            ll num = it->second;
            ll v = it->first;
            re += num * (num - 1LL);
            //cout << "*" << num << endl;
            for(it2 = same[v].begin();it2!=same[v].end();it2++)
            {
                ll samenum = it2->second;
                re -= samenum * (samenum - 1LL);
                //cout << (it2->first) << "**" << samenum << endl;
            }
        }
        cout << re << endl;
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值