文章目录

  • 前言
  • CF65A Harry Potter and Three Spells
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF65B Harry Potter and the History of Magic
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF65C Harry Potter and the Golden Snitch
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF65D Harry Potter and the Sorting Hat
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF65E Harry Potter and Moving Staircases
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code

前言

C和D题比较不错,ABE都有亿些很恶心的细节问题(尤其是E)
E题自己编写1A的读者,可以到@asta处领取8888元的现金红包(bushi)

CF65A Harry Potter and Three Spells

Description\text{Description}Description

你可以用 aaa 克沙子得到 bbb 克叶子, ccc 克叶子得到 ddd 克金子,eee 克金子得到 fff 克沙子.
给出 a,b,c,d,e,fa,b,c,d,e,fa,b,c,d,e,f,求出是否可以通过有限的沙子得到无限的金子.

Solution\text{Solution}Solution

不难得出一个有解的条件:b×d×f>a×b×cb\times d\times f>a\times b\times cb×d×f>a×b×c.
但这是建立在六个变量均正的情况.
考虑有哪些有解的情况没有考虑.

  1. c=0,d≠0c=0,d\neq0c=0,d​=0 :金子可以无中生有,根本不需要叶子
  2. a=0,b≠0,d≠0a=0,b\ne0,d\ne0a=0,b​=0,d​=0 : 叶子可以无中生有,且可以从叶子转化成金子
  3. e=0,f≠0,b≠0,d≠0e=0,f\ne0,b\ne0,d\ne0e=0,f​=0,b​=0,d​=0 : 沙子可以无中生有,但是这个其实不用特判,因为符合原来的式子

特判打全即可,不用开 longlong.

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=4e5+100;
const int mod=998244353;
//char buf[1<<23],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifint a=read(),b=read(),c=read(),d=read(),e=read(),f=read();if(b*d*f>a*c*e||(d&&c==0)||(d&&b&&a==0)) printf("Ron");else printf("Hermione");
}
/*
*/

CF65B Harry Potter and the History of Magic

Description\text{Description}Description

给你 nnn 个年份 x1...nx_{1...n}x1...n​.

请你更改一些数字,使年份按时间顺序(即非递减)排列,以使其中没有任何日期晚于 201120112011 或早于 100010001000.

在每个日期中最多只能将一位数字改成别的数字.
1≤n≤10000,1000≤xi≤99991\le n\le10000,1000\le x_i\le99991≤n≤10000,1000≤xi​≤9999.

Solution\text{Solution}Solution

不难发现贪心策略,使前面的年份尽可能的小,一定是不劣的.
分情况讨论,如果大于前一项,从高位开始尝试往低改;如果小于前一项,就从低位开始尝试往高改即可.
最后判一下是否超过 201120112011.
实现上,有一些上下取整的细节,但整体还不算太恶心.

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=4e5+100;
const int mod=998244353;
//char buf[1<<23],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
int a[1050],mi[5]={1,10,100,1000,10000};
inline int f(int x,int pos){return x%mi[pos+1]/mi[pos];
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();for(int i=1;i<=n;i++) a[i]=read();a[0]=1000;for(int i=1;i<=n;i++){if(a[i]>=a[i-1]){int d=a[i]-a[i-1];for(int k=3;k>=0;k--){int o=f(a[i],k);if(!o||d<mi[k]) continue;a[i]-=min(d/mi[k]*mi[k],o*mi[k]);break;}}else{int d=a[i-1]-a[i];for(int k=0;k<=3;k++){int o=9-f(a[i],k);if(o*mi[k]<d) continue;a[i]+=(d+mi[k]-1)/mi[k]*mi[k];//printf("k=%d o=%d d=%d add=%d\n",k,o,d,(d+mi[k]-1)/mi[k]);break;}}//printf("%d\n",a[i]);if(a[i]<a[i-1]){printf("No solution");return 0;}}if(a[n]>2011) printf("No solution");else{for(int i=1;i<=n;i++) printf("%d\n",a[i]);}
}
/*
*/

CF65C Harry Potter and the Golden Snitch

Description\text{Description}Description

有一个金色飞贼沿着 (x1,y1,z1)→(x2,y2,z2)→...→(xn,yn,zn)(x_1,y_1,z_1)\to (x_2,y_2,z_2)\to ...\to (x_n,y_n,z_n)(x1​,y1​,z1​)→(x2​,y2​,z2​)→...→(xn​,yn​,zn​) 的轨迹以 vsv_svs​ 的速度匀速运动.
哈利的最大速度是 vpv_pvp​,初始位置是 (px,py,pz)(p_x,p_y,p_z)(px​,py​,pz​).
请求出哈利抓住金色飞贼的最快时间和抓住它的位置.
n≤10000,vp≥vsn\le 10000,v_p\ge v_sn≤10000,vp​≥vs​.

Solution\text{Solution}Solution

vp≥vsv_p\ge v_svp​≥vs​ 是本题的关键条件,这意味着本题的答案是具有单调性的.
所以二分时间判断是否可以抓到即可.

注意:

  1. 虽然精度只要求到 10−610^{-6}10−6,但是由于坐标的计算会放大精度,所以我们的精度需要开到 10−1210^{-12}10−12(这里不是平方关系,只是要开小一点).
  2. 需要开 long double,否则精度太小可能会死循环.
  3. 注意不等号的精度问题.

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e4+100;
const double eps=1e-12;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
double t[N],sum[N],v;
double x[N],y[N],z[N];
double X,Y,Z,V;
inline double tim(double x,double y,double z){return sqrt((x-X)*(x-X)+(y-Y)*(y-Y)+(z-Z)*(z-Z))/V;
}
bool check(double w){for(int i=1;i<=n;i++){if(sum[i]>=w-eps){double o=(w-sum[i-1])/t[i];double xx=x[i-1]+(x[i]-x[i-1])*o,yy=y[i-1]+(y[i]-y[i-1])*o,zz=z[i-1]+(z[i]-z[i-1])*o;return tim(xx,yy,zz)-eps<w;}}return false;
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();for(int i=0;i<=n;i++) scanf("%Lf%Lf%Lf",&x[i],&y[i],&z[i]);scanf("%Lf%Lf%Lf%Lf%Lf",&V,&v,&X,&Y,&Z);for(int i=1;i<=n;i++){double d=sqrt((x[i]-x[i-1])*(x[i]-x[i-1])+(y[i]-y[i-1])*(y[i]-y[i-1])+(z[i]-z[i-1])*(z[i]-z[i-1]));t[i]=d/v;sum[i]=sum[i-1]+t[i];}if(tim(x[n],y[n],z[n])>sum[n]+eps){printf("NO\n");return 0;}double st=0,ed=sum[n];while(ed-st>eps){double mid=(st+ed)/2;if(check(mid)) ed=mid;else st=mid;}printf("YES\n%.10Lf\n",st);double w=st;for(int i=1;i<=n;i++){if(sum[i]>w-eps){double o=(w-sum[i-1])/t[i];double xx=x[i-1]+(x[i]-x[i-1])*o,yy=y[i-1]+(y[i]-y[i-1])*o,zz=z[i-1]+(z[i]-z[i-1])*o;printf("%.10Lf %.10Lf %.10Lf",xx+eps,yy+eps,zz+eps);return 0;}}
}
/*
*/

CF65D Harry Potter and the Sorting Hat

Description\text{Description}Description

有 444 个变量 G,R,S,HG,R,S,HG,R,S,H,初始的值均为 000.
给出一个长度为 nnn 的字符串,从前往后进行以下过程:

  1. 若为 G,R,S,HG,R,S,HG,R,S,H 四者之一,则给对应的变量加一.
  2. 否则(为 ??? ),就给四个变量中最小的加一,若有多个最小值,则给任意一个加一.

求处理完整个字符串后,四个变量是否有可能成为(非严格)最小值.
n≤10000n\le 10000n≤10000

Solution\text{Solution}Solution

设计状态为 (i,a,b,c,d)(i,a,b,c,d)(i,a,b,c,d) 表示进行到第 iii 个字符,四个变量分别为 a,b,c,da,b,c,da,b,c,d.
注意到,由于每次都只有在对相同的最小值加一时才会导致状态的分裂,并且可能会再后面的问号时合并状态,所以对于同一个 iii,状态数是收敛的.
直接 dfs 暴搜加 hash 去重即可.

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e4+100;
const double eps=1e-12;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
int x[N];
map<ll,bool>mp;
bool vis[5];
void dfs(int k,int a,int b,int c,int d){int mn=min(a,min(b,min(c,d)));if(k>n){if(a==mn) vis[1]=1;if(b==mn) vis[2]=1;if(c==mn) vis[3]=1;if(d==mn) vis[4]=1;return;}ll o=1ll*a*(n+1)*(n+1)*(n+1)+1ll*b*(n+1)*(n+1)+1ll*c*(n+1)+d;if(mp[o]) return;if(x[k]){if(x[k]==1) dfs(k+1,a+1,b,c,d);else if(x[k]==2) dfs(k+1,a,b+1,c,d);else if(x[k]==3) dfs(k+1,a,b,c+1,d);else if(x[k]==4) dfs(k+1,a,b,c,d+1);   }else{if(a==mn) dfs(k+1,a+1,b,c,d);if(b==mn) dfs(k+1,a,b+1,c,d);if(c==mn) dfs(k+1,a,b,c+1,d);if(d==mn) dfs(k+1,a,b,c,d+1);}mp[o]=1;
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();char c;for(int i=1;i<=n;i++){scanf(" %c",&c);if(c=='G') x[i]=1;else if(c=='H') x[i]=2;else if(c=='R') x[i]=3;else if(c=='S') x[i]=4;}dfs(1,0,0,0,0);if(vis[1]) printf("Gryffindor\n");if(vis[2]) printf("Hufflepuff\n");if(vis[3]) printf("Ravenclaw\n");if(vis[4]) printf("Slytherin\n");
}
/*
*/

CF65E Harry Potter and Moving Staircases

Description\text{Description}Description

有一个 nnn 个点 mmm 条边的无向图,哈利初始在结点 111,哈利可以沿着边任意移动,过程中任意时刻可以选择一条边,改变它的一个端点,但是每条边只能被修改一次.
请构造一种方案使哈利走遍所有楼层,或者报告无解.
n≤105,m≤2×105n\le 10^5,m\le 2\times10^5n≤105,m≤2×105

Solution\text{Solution}Solution

阴间大特判题.
容易找到一种比较正确的整体方案:dfs,过程中——

  1. 若出边连向走过的结点,则直接把边改向一个未走过的结点,递归 dfs.
  2. 若出边连向未走过的结点,则先递归 dfs,回溯时在把边改向一个未走过的结点,递归 dfs.

不难发现这样一定是最优的.
然后就是 通过观察 WA 的数据 处理亿点点细节问题:

  1. 改边连向的点应该优先连向有度数的点.
  2. 有可能会出现 111 没有度数但存在解的情况,这时候需要尝试把一条边直接改为连向 111,同时这个边不应该是一条边连接两个点的简单图形.(否则改完还是会死掉)
  3. 改为连向 111 的边应该优先选择成环的边,这样会更优.

具体实现留给读者自行思考.(或者参考我实现丑的一批的代码)

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=4e5+100;
const double eps=1e-12;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
struct node{int to,nxt;
}p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt;return;
}
int jd[N],du[N];
set<int>s1,s2;
int dfn[N<<2],tim,tot;
struct edge{int x,y,id;
}e[N];
int siz[N];
int ans[N],num;
int flag,O,ID;
void print(){int pl(1);if(!O) flag=0;printf("YES\n%d\n",tot+flag);for(int i=1;i<=tim+1;i++){if(dfn[i]) ans[++num]=dfn[i];else{printf("%d ",num);for(int j=1;j<=num;j++) printf("%d ",ans[j]);putchar('\n');   num=0;if(pl<=tot){printf("%d %d %d\n",e[pl].id,e[pl].x,e[pl].y);   ++pl;}}if(i==1&&flag){printf("1 1\n%d %d 1\n",ID,O);num=0;}}return;
}
int fa[N];
vector<int> v[N];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
bool vis[N];
void dfs(int x){dfn[++tim]=x;vis[x]=1;for(int i=fi[x];~i;i=p[i].nxt){if(jd[i]==1) continue;int f=jd[i];jd[i]=jd[i^1]=1;int to=p[i].to;//printf("x=%d to=%d\n",x,to);dfs(to);dfn[++tim]=x;if((!s1.empty()||!s2.empty())&&!f){int o;if(!s1.empty()) o=(*s1.begin()),s1.erase(o);else o=(*s2.begin()),s2.erase(o);//printf("x=%d o=%d\n",x,o);dfn[++tim]=0;e[++tot]=(edge){x,o,i/2+1};dfs(o);dfn[++tim]=x;}}return;
}
int E;
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmemset(fi,-1,sizeof(fi));cnt=-1;  n=read();m=read();for(int i=1;i<=n;i++) fa[i]=i;for(int i=1;i<=m;i++){e[i].x=read();e[i].y=read();++du[e[i].x];++du[e[i].y];if(find(e[i].x)==find(e[i].y)){E=i;}else fa[find(e[i].x)]=find(e[i].y);}if(du[1]==0){flag=1;if(E){e[E].y=1;O=e[E].x;ID=E;}else{for(int i=1;i<=m;i++){if(du[e[i].x]<=1) swap(e[i].x,e[i].y);if(du[e[i].x]>1){e[i].id=1;O=e[i].x;ID=i;e[i].y=1;break;}}}}memset(du,0,sizeof(du));for(int i=1;i<=n;i++) fa[i]=i;for(int i=1;i<=m;i++){int x=e[i].x,y=e[i].y;addline(x,y);addline(y,x);fa[find(x)]=find(y);++du[x];++du[y];if(e[i].id) jd[cnt]=jd[cnt^1]=2;}//for(int i=1;i<=n;i++) debug("i=%d fa=%d\n",i,fa[i]);for(int i=2;i<=n;i++){if(i==find(i)&&find(1)!=i){if(du[i]) s1.insert(i);else s2.insert(i);}}dfs(1);if(!s1.empty()||!s2.empty()) printf("NO\n");else print();return 0;
}
/**/

codeforces:65相关推荐

  1. Educational Codeforces Round 65 (Rated for Div. 2) C. News Distribution

    链接:https://codeforces.com/contest/1167/problem/C 题意: In some social network, there are nn users comm ...

  2. Educational Codeforces Round 65 (Rated for Div. 2)A. Telephone Number

    题目来源:https://codeforces.com/contest/1167/problem/A 题意:给你一个数字串问你能不能从中截取一个以8开头的长为11的电话号码. 思路:遍历0到n-11看 ...

  3. Codeforces:896C-Willem, Chtholly and Seniorious(odt模板)

    题目链接:http://codeforces.com/contest/896/problem/C C. Willem, Chtholly and Seniorious time limit per t ...

  4. Silverlight实用窍门系列:65.Silverlight的数据模板DataTemplate(一)使用数据模板

    在Silverlight中,我们的数据列表显示控件有ListBox.DataGrid等.对于显示出来的数据条目样式外观的管理是通过DataTemplate(数据模板)来完成的.本节将从DataTemp ...

  5. Educational Codeforces Round 65 (Rated for Div. 2) D. Bicolored RBS

    传送门 参考资料: [1]:https://www.cnblogs.com/wangrunhu/p/10880130.html [2]:https://blog.csdn.net/weixin_432 ...

  6. codeforces:E1. Divisible Numbers (easy version)【数论 + 复杂度计算 + 分解质因数】

    目录 题目截图 题目分析 想法1:遍历所有可能的xy(tle) 想法2:遍历可能的x(accepted) 总结 题目截图 题目分析 想法1,遍历所有kab作为xy的所有可能值,找到其所有因子,然后看看 ...

  7. codeforces:E. MEX and Increments【贪心 + 略加优化】

    分析 mex(a) 表示不在a中的最小非负整数 ans[i] 表示最少的操作数使得mex(a) = i 我们用个counter记录一下原始每个位置出现的次数 我们的思路很简单:找出缺口,然后把多余的平 ...

  8. codeforces:C. Another Array Problem【分类讨论 + 找规律】

    目录 题目截图 题目分析 ac code 总结 题目截图 题目分析 做cf题目别老想着套算法模版 找规律才是正道,这就是所谓的「思维」 n = 2很简单 n >= 4: # 肯定有一个最大值,不 ...

  9. codeforces:C. Set Construction【构造 + 入度观察】

    目录 题目截图 题目分析 ac code 总结 题目截图 题目分析 题目要找n个集合 给出一个矩阵b 如果bij = 1,表示第i个集合为第j个集合的真子集 bij = 0,表示不是真子集 寻找集合间 ...

最新文章

  1. java二维数组矩阵_java使用二维数组开发五子棋
  2. 2013:奇虎360最好的时光
  3. linux c dup dup2 重定向函数简介
  4. Java编译器、JVM、解释器
  5. linux 相关系统参数调优(特别针对网络传输,大量TIME_WAIT 的TCP状态的情况)
  6. 最强战队出炉,2020腾讯广告算法大赛圆满落幕
  7. k折交叉验证优缺点_R语言中K邻近算法的初学者指南:从菜鸟到大神(附代码&链接)...
  8. angularjs 实例_AngularJS包含示例教程
  9. 不要再闲玩啦!博主手把手带你两个月入门自然语言处理,还不赶紧碗里来!...
  10. 关键字 : this /self / parent
  11. AI和大数据结合,智能运维平台助力流利说提升竞争力
  12. Unity 根据文件路径批量修改图片格式
  13. 主流数据库优缺点以及性能分析
  14. JAVA智能分析的简单聚众筹平台计算机毕业设计Mybatis+系统+数据库+调试部署
  15. Spring中的依赖注入(10级学员 韩晓爽课堂总结)
  16. 极端类别不平衡数据下的分类问题研究综述,终于有人讲全了!
  17. windows无法完成安装若要在此计算机,windows无法完成安装.若要在此
  18. 金仓数据库 KingbaseES 异构数据库移植指南 (4. 应用迁移流程)
  19. “创新驱动的结构化思维”培训
  20. [ BZOJ 2757 ]Blinker的仰慕者

热门文章

  1. 程序员江湖鄙视链大全,看看你处于链条的哪一级?
  2. 盘点那些让程序员目瞪口呆的Bug都有什么?
  3. linux accept过程,Linux协议栈accept和syn队列问题
  4. 截获android屏幕服务,如何捕获android设备屏幕内容?
  5. ab压力测试_Apache ab压力测试的知识点
  6. 网站logo放在服务器,自己建网站如何设计网站LOGO
  7. linux删除第二次出现的字符,linux下 怎样删除文件名中包含特殊字符的文件
  8. netcore读取json文件_【NET Core】.NET Core中读取json配置文件
  9. python中log1p用法_python中logging模块的基本用法
  10. moore 数据集_警报数据集(alarm dataset)_机器学习_科研数据集