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);
}
}