2021-11-12 (2018 CCPC 吉林站)

A - The Fool

题意:

给一个数n,你需要求出n/1+n/2+...+n/n的和,判断和为奇或偶,输出。

思路: 

打表可以发现前三个数为奇数,五个为偶数,七个为奇数,九个为偶数,即公差为2的等差数列,可以发现3,5,7,9而1-3 即大于等于1的平方,小于2的平方,4-8,即大于等于2的平方,小于3的平方,9-15 即大于等于3的平方,小于4的平方。所以直接sqrt(n)去判断即可,或者看这里

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    for(int i=1; i<=t; i++)
    {
        long long n;
        cin>>n;
        n=sqrt(n);
        if(n%2==0)
            cout<<"Case "<<i<<""<<": even"<<endl;

        else
            cout<<"Case "<<i<<""<<": odd"<<endl;
    }
}

 B - The World

题意:

世界可以指示世界旅行,特别是大规模旅行。你可能很幸运,开始了为期六个月的海外旅行,或者在海外工作、学习或生活了很长一段时间。同样,这张卡片加强了普遍理解和全球意识,你将对来自世界各地的人和文化有一种新的欣赏。

世界各地都有不同的时区,导致时差。在这里,您可以了解到几个著名的首都及其相应的时区。

北京-中国-UTC+8(中国标准时间)

华盛顿-美国-UTC-5(东部标准时间)

伦敦-英国-UTC(格林威治标准时间)

莫斯科-俄罗斯-UTC+3(莫斯科时间)

给定一个城市的当地时间,您需要计算上述首都中另一个特定城市的日期和当地时间。

思路:

小时的取值范围是1到12,半夜12点表示为12:00AM,中午12:00表示为12:00PM。并且半夜12点是新的一天的开始。

时间转换之后时钟大于等于24代表是在Tomorrow,如果小于0代表在Yesterday。

代码:

#include<bits/stdc++.h>
using namespace std;
map<string,int> mp;
string a,b,p;
int main()
{
    mp["Beijing"]=8;
    mp["Washington"]=-5;
    mp["London"]=0;
    mp["Moscow"]=3;
    int TT=0;
    int T;scanf("%d",&T);
    int h,m;
    while(T--)
    {
        scanf("%d:%d",&h,&m);
        cin>>p;
        if(p=="PM"&&h!=12)
            h+=12;
        if(p=="AM"&&h==12)
            h-=12;
        cin>>a>>b;
        h+=(mp[b]-mp[a]);
        printf("Case %d: ",++TT);
        if(h>=24)
            {printf("Tomorrow ");h-=24;}
        else if(h<0)
            {printf("Yesterday ");h+=24;}
        else
            printf("Today ");
        if(h>12)
            printf("%d:%02d ",h-12,m);
        else if(h>0)
            printf("%d:%02d ",h,m);
        else
            printf("12:%02d ",m);
        if(h>=12)
            printf("PM\n");
        else
            printf("AM\n");
    }
    return 0;
}

C - Justice

题意:

t组样例,每组样例中一个n,接下来输入n个数字ki,每个数字你要将它看作2的ki次方分之一,问是否能将这些数字分成两组,并且使两组的和都大于等于1/2,不能输出NO,可以的话输出YES,并在下一行输出这些数字都被分到了哪一组,两组组号为0和1。

思路:

分成两堆,相同的数字就可以合并为新的一个,然后就不会写了QAQ。看了别人的题解

在这里解释一下为什幺要合并出1,因为你合并最后要求的结果两组都大于等于1/2,分母即2的1次方为成功的边界,只有当n个数整理出的和小于等于1时,才是YES。第二种比较详细。

第一种

第二种

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e5 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int vis[MAXN];
PII a[MAXN];
int main()
{
    int t;
    scanf("%d", &t);
    for (int Case = 1; Case <= t; Case++)
    {
        memset(vis, 0, sizeof(vis));
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i].first), a[i].second = i;
        sort(a + 1, a + 1 + n);
        int pre = 1;
        int cnt1 = 1, cnt2 = 1;
        bool flag = true;
        for (int i = 1; i <= n; i++)
        {
            while (pre < a[i].first && cnt1 + cnt2 <= n - i + 1)
            {
                cnt1 <<= 1;
                cnt2 <<= 1;
                pre++;
            }
            if (cnt1 + cnt2 > n - i + 1)
            {
                flag = false;
                break;
            }
            if (cnt1)
            {
                cnt1--;
                vis[a[i].second] = 1;
            }
            else
                cnt2--;
            if (!cnt1 && !cnt2)
                break;
        }
        printf("Case %d: ", Case);
        if (flag)
        {
            printf("YES\n");
            for (int i = 1; i <= n; i++)
                printf("%d", vis[i]);
            printf("\n");
        }
        else
            printf("NO\n");
    }
    return 0;
}

F - The Hermit 

题意:

对于每个点 i, 它能覆盖范围是 [i - ri + 1, i + ri - 1],且对于任意相邻点i,i + 1,i + 1 的覆盖的左边界一定大于等于 i 覆盖的左边界,对于每个点 i,它的权值定义为合法k的数量,定义k合法:k < i,且 k 在 i 的覆盖范围内,且存在一个点 j,k < j < i,且 dist(k, j) >= dist(j, i),且 i 和 k 都在 j 的覆盖范围内。要求每个点的权值异或和

思路:

对于 ri < 3 的点,显然权值为0,对于 ri >= 3 的点,我们由题意得,ri - 1 覆盖的左边界一定 <= ri 覆盖的左边界,也就是说我设置 j = i - 1,其他 i 左边能覆盖的点都可以作为合法的 k 点,也就是说, i 的权值为 ri - 2。
代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e6 + 10, N = 1e6;
int main() {
    int T, kase = 0;
    scanf("%d", &T);
    while (T--) {
        int n, x, ans = 0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &x);
            if (x >= 3)
                ans ^= (x - 2);
        }
        printf("Case %d: %d\n", ++kase, ans);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值