A - The Fool
数论分块暴力求和
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
int main()
{//IO;int T=1;cin>>T;for(int ca=1;ca<=T;ca++){int n;cin>>n;ll s=0;for(int l=1,r;l<=n;l=r+1){r=n/(n/l);s=(s+1ll*(r-l+1)%2*(n/l))%2;}if(s%2) printf("Case %d: odd\n",ca);else printf("Case %d: even\n",ca);}return 0;
}
B - The World
这题就离谱??? 不明白下面的一二两个设定?很反直觉啊啊啊
- 12:00 AM 是凌晨十二点
- 12:00 PM 是中午十二点
- h=0输出12
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
map<string,int> mp;
int main()
{//IO;int T=1;cin>>T;mp["Beijing"] = 8;mp["Washington"] = -5;mp["London"] = 0;mp["Moscow"] = 3;for(int ca=1;ca<=T;ca++){int h,m;string op,from,to;scanf("%d:%d",&h,&m);cin>>op>>from>>to;if(h==12) h=0;if(op=="PM") h+=12;h+=mp[to]-mp[from];int f=0;string now;if(h<0) {f=-1;h+=24;}else if(h>=24){f=1;h-=24;}if(h>=12) {h-=12;now="PM";}elsenow="AM";if(h==0) h+=12;// 输出printf("Case %d: ",ca);if(f==-1) printf("Yesterday %d:%02d ", h, m);else if(f==0)printf("Today %d:%02d ", h, m);else printf("Tomorrow %d:%02d ", h, m);cout<<now<<'\n';}return 0;
}
C - Justice
自己想的辣鸡代码
刚开始没思路于是想猜结论:只要和大于1就一定能够分成两组,因为它是以12k\frac{1}{2^k}2k1为一份,怎么分组就贪心分一下,对于较大的k由于小数太小,没法存储,我当时想的是忽略这些值(k>25的时候小数已经非常小可能对答案没影响),于是写出了下面辣鸡代码wa了
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const double eps=1e-14;
const int N=100010;
double two[110];
int ans[N];
int n;
struct node
{int k,id;bool operator<(const node& o) const {return k<o.k;}
}q[N];
int main()
{//IO;int T=1;cin>>T;two[0]=1.0;for(int i=1;i<=100;i++) two[i]=two[i-1]/2.0;for(int ca=1;ca<=T;ca++){cin>>n;for(int i=1;i<=n;i++){cin>>q[i].k;q[i].id=i;}sort(q+1,q+1+n);double s=0.0;for(int i=1;i<=n;i++){if(q[i].k>=100) {ans[q[i].id]=1;continue;}if(s+eps>0.5) ans[q[i].id]=1;elseans[q[i].id]=0;s+=two[q[i].k];}if(s+eps>1.0) {printf("Case %d: YES\n",ca);for(int i=1;i<=n;i++) cout<<ans[i];cout<<'\n';}elseprintf("Case %d: NO\n",ca);}return 0;
}
正解
我们需要凑一个12\frac1221,或者2个14\frac1441,或者4个18…\frac18\dots81…
不难发现如果当前需要凑cntcntcnt个12k\frac1{2^k}2k1,那么如果现在没有12k\frac1{2^k}2k1,我们不得不用12j(j>k)\frac1{2^j}(j>k)2j1(j>k)来凑,不难发现我们现在需要凑cnt×2j−kcnt×2^{j-k}cnt×2j−k个12j\frac1{2^j}2j1
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=100010;
struct node
{int k,id;bool operator<(const node&o) const {return k<o.k;}
}q[N];
int ans[N];
int n;
int main()
{//IO;int T=1;cin>>T;for(int ca=1;ca<=T;ca++){cin>>n;for(int i=1;i<=n;i++){ans[i]=0;cin>>q[i].k;q[i].id=i;}sort(q+1,q+1+n);bool ok=0;int pre=1;int cnt1=1,cnt2=1;for(int i=1;i<=n;i++){while(cnt1+cnt2<=n-i+1&&pre<q[i].k)//少个+1都会wa 感觉数据有点诡异啊{cnt1*=2;cnt2*=2;pre++;}if(cnt1+cnt2>n-i+1) break;if(cnt1>0){cnt1--;ans[q[i].id]=1;}elsecnt2--; if(cnt1<=0&&cnt2<=0) {ok=1;break;}}if(!ok) printf("Case %d: NO\n",ca);else{printf("Case %d: YES\n",ca);for(int i=1;i<=n;i++) cout<<ans[i];cout<<'\n';}}return 0;
}
D - The Moon
一看就是个概率dp的题,由于自己概率dp的题写的太少了,然后就写不出来,看的题解。
设fif_ifi是当q=iq=iq=i是的期望次数
fi=p(1−q)(1+fq+2%)+pq+(1−p)(1+fq+1.5%)f_i=p(1-q)(1+f_{q+2\%})+pq+(1-p)(1+f_{q+1.5\%})fi=p(1−q)(1+fq+2%)+pq+(1−p)(1+fq+1.5%)
记忆化搜索即可
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int N=1010;
double f[N];
int p;
double dfs(int q)
{if(f[q]>=0) return f[q];if(q>=1000)return f[q]=100.0/(1.0*p);f[q]=(1.0*p/100.0)*(1.0-1.0*q/1000.0)*dfs(min(1000,q+20))+(1.0-1.0*p/100.0)*dfs(min(1000,q+15))+1.0;return f[q];
}
int main()
{//IO;int T=1;cin>>T;for(int ca=1;ca<=T;ca++){for(int i=0;i<=1000;i++) f[i]=-1;;cin>>p;printf("Case %d: %.6lf\n",ca,dfs(20));}return 0;
}
F - The Hermit
这题非常巧妙啊
结论:对于第iii个站[i−radi+1,i−2][i-rad_i+1,i-2][i−radi+1,i−2]范围的基站都能够接收到第iii个站的perfect signal
仔细想想可知道根据i−radi+1≤i+1−radi+1+1i - rad_i + 1 ≤ i + 1 - rad_{i+1} + 1i−radi+1≤i+1−radi+1+1条件,就能使[i−radi+1,i−2][i-rad_i+1,i-2][i−radi+1,i−2]的基站满足条件。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int N=100010;
int main()
{//IO;int T=1;cin>>T;for(int ca=1;ca<=T;ca++){int n;cin>>n;int res=0;for(int i=1;i<=n;i++){int a;cin>>a;res^=max(0,a-2);}printf("Case %d: %d\n", ca, res);}return 0;
}
I - Strength
贪心+模拟,1发A有点高兴。
先判断是否能够打死完对面的怪物,如果能够打完那么先用最小的代价把防御类型的干掉(只需找一个大于防御值的最小的攻击即可)
如果不能打死完,那么我们只需要用最大的攻击最小的即可,欺负弱小
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int N=100010;
int n,m;
int a[N];
int b[N];
bool st1[N],st2[N];
int main()
{//IO;int T=1;cin>>T;for(int ca=1;ca<=T;ca++){memset(st1,0,sizeof st1);memset(st2,0,sizeof st2);vector<int> ak,df;cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i];sort(a+1,a+1+n);for(int i=1;i<=m;i++) cin>>b[i];for(int i=1;i<=m;i++){int op;cin>>op;if(op) df.push_back(b[i]);else ak.push_back(b[i]);}sort(df.begin(),df.end());sort(ak.begin(),ak.end());int cnt=0;int j=1;for(auto t:df){while(j<=n&&a[j]<t) j++;if(a[j]>=t) {st1[j]=1;cnt++;j++;}else break;}int res1=0,res2=0;if(cnt==df.size()){int cnt=0,j=1;for(auto t:ak){while(j<=n&&!st1[j]&&a[j]<t) j++;if(a[j]>=t){res1+=a[j]-t;j++;st2[j]=1;cnt++;}else break;}if(cnt==ak.size()){for(int i=1;i<=n;i++)if(!st1[i]&&!st2[i]) res1+=a[i];}else{res1=0;int j=n;for(auto t:ak){if(!st1[j]&&a[j]>=t) {res2+=a[j]-t;j--;}else break;}}}else{int j=n;for(auto t:ak){if(a[j]>=t) {res2+=a[j]-t;j--;}else break;}}printf("Case %d: %d\n", ca, max(res1, res2));}return 0;
}
F - Lovers
线段树待补