2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest(solved 8/11)
这套题似乎是省选前做的,一直没来写题解~~~补上补上>_<
链接:http://codeforces.com/gym/101147
一样先放上惨不忍睹的成绩好了~~~
Problem A 1Y(2h52min)
Problem B DNF
Problem C DNF
Problem D 1Y(3min)
Problem E 2Y(19min)
Problem F DNF
Problem G 6Y(2h40min)
Problem H 1Y(36min)
Problem I 2Y(4h55min)
Problem J DNF
Problem K DNF
总之我非常非常菜就对了啦~
Problem A:
一个很棒棒的博弈题呢~
博弈题不会的时候,不如打个表找找规律~~~
然后分类讨论一下,
a是奇数的时候,b的奇偶性决定了sg函数的值,
a是偶数的时候,b%(a+1)决定了sg函数的值,(这里还要分类讨论一下)
于是全部xor一下就做完了。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int T,ans,n,a,b;
int main()
{
freopen("powers.in","r",stdin);
T=read();
while (T--)
{
ans=;
n=read();
for (int i=;i<=n;i++)
{
a=read(),b=read();
if (a%==)
{
if (b%==) ans^=;
}
else
{
b=b%(a+);
if (b==a) ans^=;
if (b%==) ans^=;
}
}
if (ans==) printf("%d\n",); else printf("%d\n",);
}
return ;
}
Problem B:
这题好像是个计算几何啊。。。不做不做(这是virtual participate时候的我),啊哼>_<
其实这题很好做啊,把矩形之间两两最短距离细节全部判出来,
然后直接跑SPFA最短路不就好了嘛。
注意细节啊~~~
代码如下:
#include <bits/stdc++.h>
#define Maxn 107
#define Maxm 200007
#define inf 1500000007
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int T,n,L,R,cnt,s,t;
int d[Maxn],h[Maxn],k[Maxn],w[Maxn];
int pre[Maxm],other[Maxm],last[Maxm];
int que[Maxm*];
double dis[Maxn],len[Maxm];
bool vis[Maxn];
void insert(int u,int v,double d)
{
other[++cnt]=v,pre[cnt]=last[u],last[u]=cnt,len[cnt]=d;
other[++cnt]=u,pre[cnt]=last[v],last[v]=cnt,len[cnt]=d;
}
void spfa()
{
int lx=,rx=;
memset(vis,false,sizeof(vis));
vis[s]=true;
for (int i=;i<=t;i++) dis[i]=inf*1.0;
que[]=s;
while (lx<rx)
{
int u=que[++lx];
for (int q=last[u];q;q=pre[q])
{
int v=other[q];
if (dis[v]>dis[u]+len[q])
{
dis[v]=dis[u]+len[q];
if (!vis[v])
{
vis[v]=true;
que[++rx]=v;
}
}
}
vis[u]=false;
}
}
int main()
{
freopen("street.in","r",stdin);
T=read();
while (T--)
{
n=read(),L=read(),R=read();
for (int i=;i<=n;i++)
h[i]=read(),w[i]=read(),d[i]=read(),k[i]=read();
cnt=;
memset(last,,sizeof(last));
s=,t=n+;
insert(s,t,1.0*L);
for (int i=;i<=n;i++) insert(s,i,d[i]*1.0);
for (int i=;i<=n;i++) insert(i,t,(L-h[i]-d[i])*1.0);
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++)
{
int dely=abs(d[j]+h[j]-d[i]);
dely=min(dely,abs(d[i]+h[i]-d[j]));
if (k[i]!=k[j]&&d[i]+h[i]>=d[j]&&d[i]+h[i]<=d[j]+h[j]) dely=;
if (k[i]!=k[j]&&d[j]+h[j]>=d[i]&&d[j]+h[j]<=d[i]+h[i]) dely=;
if (k[i]==k[j]||w[i]+w[j]>=R) insert(i,j,dely*1.0); else
{
int delx=R-w[i]-w[j];
insert(i,j,(double)sqrt(1LL*dely*dely+1LL*delx*delx));
}
}
spfa();
printf("%.6lf\n",dis[t]);
}
fclose(stdin);
return ;
}
Problem D:
组合数会不会呀~~~
写程序会不会呀~~~(捂脸熊)
代码如下:
#include <bits/stdc++.h>
using namespace std;
int T,n,m;
long long pre[];
int main()
{
freopen("popcorn.in","r",stdin);
cin>>T;
pre[]=;
for (int i=;i<=;i++) pre[i]=1LL*pre[i-]*i;
while (T--)
{
cin>>n>>m;
long long ans=;
for (int i=n-m+;i<=n;i++) ans=1LL*ans*i;
ans=ans/pre[m];
cout << ans << endl;
}
return ;
}
Problem E:
这题时间限制辣么长,是不是可以暴力大搜索啊~(当然不行。。。)
我们对于每一个点i,将i和i-di和i+di分别连边,然后直接SPFA最短路就行了。
(其实这题我的第一反应是DP呢。。。)
代码如下:
#include <bits/stdc++.h>
#define Maxn 100007
#define Maxm 1000007
#define inf 1000000007
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int T,n,cnt;
int d[Maxn];
int last[Maxm],pre[Maxm],other[Maxm],dis[Maxn],que[Maxm];
bool vis[Maxn];
void insert(int u,int v)
{
other[++cnt]=v,pre[cnt]=last[u],last[u]=cnt;
}
void spfa()
{
memset(que,,sizeof(que));
for (int i=;i<=n;i++) dis[i]=inf;
dis[n]=;
int lx=,rx=;
vis[n]=true;
que[]=n;
while (lx<rx)
{
int u=que[++lx];
vis[u]=false;
for (int q=last[u];q;q=pre[q])
{
int v=other[q];
if (dis[v]>dis[u]+)
{
dis[v]=dis[u]+;
if (!vis[v])
{
vis[v]=true;
que[++rx]=v;
}
}
}
}
}
int main()
{
freopen("jumping.in","r",stdin);
T=read();
while (T--)
{
n=read();
memset(last,,sizeof(last));
for (int i=;i<=n;i++) d[i]=read();
cnt=;
for (int i=;i<n;i++)
{
if (i+d[i]<=n) insert(i+d[i],i);
if (i-d[i]>) insert(i-d[i],i);
}
spfa();
for (int i=;i<=n;i++)
if (dis[i]<=inf/) printf("%d\n",dis[i]); else printf("%d\n",-);
}
return ;
}
Problem G:
这题的答案就是第二类斯特林数再乘上一个阶乘就好了,
然后稍微与处理一下就好了的吧。。。
代码如下:
#include <bits/stdc++.h>
#define modp 1000000007
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int T,n,k;
long long f[][],pre[];
int main()
{
freopen("galactic.in","r",stdin);
T=read();
memset(f,,sizeof(f));
f[][]=;
for (int i=;i<=;i++)
{
f[i][i]=;
for (int j=;j<=i;j++)
f[i][j]=(1LL*j*f[i-][j]+f[i-][j-])%modp;
}
pre[]=;
for (int i=;i<=;i++) pre[i]=(1LL*pre[i-]*i)%modp;
while (T--)
{
n=read(),k=read();
if (k>n) printf("%d\n",); else printf("%d\n",(1LL*pre[k]*f[n][k])%modp);
}
return ;
}
Problem H:
这题不是10*10*10的DP一下就好了嘛。。。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int T,n,w[][][],f[][][];
int main()
{
freopen("commandos.in","r",stdin);
T=read();
while (T--)
{
n=read();
memset(w,,sizeof(w));
memset(f,,sizeof(f));
for (int i=;i<=n;i++)
{
int f=read(),y=read(),x=read(),h=read();
w[f][y][x]=h;
}
for (int i=;i;i--)
for (int j=;j<=;j++)
for (int k=;k<=;k++)
{
f[i][j][k]=max(f[i+][j][k], max(f[i][j-][k],f[i][j][k-]))+w[i][j][k];
}
printf("%d\n",f[][][]);
}
return ;
}
Problem I:
这题是个可做的计算几何呢~~~
首先我们把每个圆与x轴的交点都预处理出来,
然后排个序,类似扫描线的从左到右扫一遍就行了。
代码如下:
#include <bits/stdc++.h>
#define Maxn 100007
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int T,n,R,cnt;
pair <double,int> s[*Maxn];
int main()
{
freopen("walk.in","r",stdin);
T=read();
while (T--)
{
n=read(),R=read();
cnt=;
for (int i=;i<=n;i++)
{
int x=read(),y=read(),r=read();
if (!(r>R||y>R-r||y<r-R))
{
double dis=sqrt(1.0*(R-r)*(R-r)-1.0*y*y);
s[++cnt]=make_pair(-1.0*dis+1.0*x,-r);
s[++cnt]=make_pair(1.0*dis+1.0*x,r);
}
}
sort(s+,s+cnt+);
long long ans=,now=;
for (int i=;i<=cnt;i++)
{
now+=s[i].second;
ans=max(ans,-now);
}
cout<<ans<<endl;
}
return ;
}
Problem J:
为什么你们这个题都会做啊,我就不会。。。
我们对整个树做一下DFS,然后在DFS的时候动态维护出当前的路径,
对于当前的节点我们考虑它对答案的贡献度,
然后发现其实只要在路径上二分以下就做完了。
代码如下:
#include <bits/stdc++.h>
#define Maxn 1000007
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int T,n,cnt;
int val[Maxn];
long long path[Maxn],ans[Maxn],depth[Maxn];
int pre[Maxn],other[Maxn],last[Maxn],len[Maxn];
int father[Maxn];
void insert(int u,int v,int dis)
{
other[++cnt]=v,pre[cnt]=last[u],len[cnt]=dis,last[u]=cnt;
}
void dfs(int u,int fa,int num)
{
for (int q=last[u];q;q=pre[q])
{
int v=other[q];
if (v!=fa)
{
father[v]=u;
path[num]=v;
depth[num]=depth[num-]+len[q];
int pos=lower_bound(depth,depth+num+,depth[num]-val[v])-depth;
if (pos<num)
{
++ans[u];
--ans[father[path[pos]]];
}
dfs(v,u,num+);
ans[u]+=ans[v];
}
}
}
int main()
{
freopen("car.in","r",stdin);
T=read();
while (T--)
{
n=read(),cnt=;
memset(last,,sizeof(last));
for (int i=;i<=n;i++) val[i]=read();
for (int i=;i<n;i++)
{
int u=read(),v=read(),dis=read();
insert(u,v,dis),insert(v,u,dis);
}
memset(depth,,sizeof(depth));
memset(path,,sizeof(path));
memset(ans,,sizeof(ans));
path[]=,depth[]=;
dfs(,-,);
for (int i=;i<=n;i++) printf("%lld ",ans[i]);
printf("\n");
}
return ;
}
2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest(solved 8/11)的更多相关文章
- ACM ICPC, JUST Collegiate Programming Contest (2018) Solution
A:Zero Array 题意:两种操作, 1 p v 将第p个位置的值改成v 2 查询最少的操作数使得所有数都变为0 操作为可以从原序列中选一个非0的数使得所有非0的数减去它,并且所有数不能 ...
- ACM ICPC, Amman Collegiate Programming Contest (2018) Solution
Solution A:Careful Thief 题意:给出n个区间,每个区间的每个位置的权值都是v,然后找长度为k的区间,使得这个区间的所有位置的权值加起来最大,输出最大权值, 所有区间不重叠 思路 ...
- Egyptian Collegiate Programming Contest 2017 (ACM ECPC 2017) - original tests edition
题目链接:https://codeforces.com/gym/101856 D. Dream Team 题意:n个点,让你连边成为一棵树,边权为顶点的GCD(u,v).求所有边权和的最大值. 思路: ...
- 2017 ACM Arabella Collegiate Programming Contest(solved 11/13)
省选考前单挑做点ACM练练细节还是很不错的嘛- 福利:http://codeforces.com/gym/101350 先来放上惨不忍睹的virtual participate成绩(中间跑去食堂吃饭于 ...
- Gym100814B Gym100814F Gym100814I(异或) ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (2015) Arab Academy for Science and Technology
今日份的训练题解,今天写出来的题没有昨天多,可能是因为有些事吧... Gym100814B 这个题就是老师改卷子,忘带标准答案了,但是他改了一部分卷子,并且确定自己改的卷子没出错,他想从改过的卷子里把 ...
- 2017 ACM Arabella Collegiate Programming Contest(solved 9/13, complex 12/13)
A.Sherlock Bones 题意: 给出长度为n的01串,问f(i,j)=f(j,k),(i<j<k)的i,j,k取值种数.其中f(i,j)表示[i,j]内1的个数, 且s[j]必须 ...
- ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2015)
A.Arcade Game(康拓展开) 题意: 给出一个每个数位都不同的数n,进行一场游戏.每次游戏将n个数的每个数位重组.如果重组后的数比原来的数大则继续游戏,否则算输.如果重组后的数是最大的数则算 ...
- Codeforces Gym100814 I.Salem-异或 (ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (2015) Arab Academy for Science and Technology)
这个题就是二进制,找两个数相应的二进制相对应的位置上数不同的最多的个数.异或写就可以. 一开始还想麻烦了,找出来最大的偶数和最大的奇数,最小的偶数和最小的奇数,但是这样想考虑的不全.因为范围比较小,直 ...
- Codeforces Gym100814 F.Geometry (ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (2015) Arab Academy for Science and Technology)
这个题真的是超级超级水啊,哈哈哈哈哈哈.不要被题面吓到,emnnn,就这样... 代码: 1 #include<iostream> 2 #include<cstring> 3 ...
随机推荐
- tar命令,vi编辑器
一.将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖): [root@localhost /]# cat /etc/passwd /etc/group > 1.txt ...
- javaScript编辑器sublime的安装
最近在学习js,学习任何一门语言之前,当然免不了最初的环境安装: 见:http://www.cnblogs.com/zhcncn/p/4113589.html
- Android 文件管理器通用类 FileUtil
1.整体分析 1.1.源代码如下,可以直接Copy. public class FileUtil { private FileUtil() { } //****系统文件目录************** ...
- 第四模块:网络编程进阶&数据库开发 口述
进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 子进程死了之后 ,父进程关闭的时候要清理掉子进程的僵尸进程(收尸),孤儿进程是指父进程先死掉了的,交给init管理. join() 等待子进 ...
- CodeForces 785E Anton and Permutation 分块
题意: 有一个\(1 \sim n\)的排列\(A\),有\(q\)个询问: 交换任意两个元素的位置,求交换之后排列的逆序数 分析: 像这种不太容易用线段树,树状数组维护的可以考虑分块 每\(\sqr ...
- python几个复习例子
1.实现1-100的所有的和,程序代码如下: sum = 0 for i in xrange(1,101): sum +=i print (sum) 程序运行结果: 2.实现1-500所有奇数的和,程 ...
- js模板引擎之 Handlebars 基本用法
模板引擎比较久远的一个技术,常见的模板引擎有 baiduTemplate(百度)\artTemplate(腾讯)\juicer(淘宝)\doT\ tmpl\ handlebars\ easyTempl ...
- react基本知识点合集
妹子UI里面有React的相关组件与用法:http://amazeui.org/react/components React官方网站:https://facebook.github.io/react/ ...
- 对setTimeout函数的理解
之前去面试一家公司时,面试官出了一道关于js的setTimeout函数的题目: /* *面试官给的原题目如下: *执行mytest()后,控制台输出内容是_____ *function mytest( ...
- 《数据结构》C++代码 邻接表与邻接矩阵
上一篇“BFS与DFS”写完,突然意识到这个可能偏离了“数据结构”的主题,所以回来介绍一下图的存储:邻接表和邻接矩阵. 存图有两种方式,邻接矩阵严格说就是一个bool型的二维数组,map[i][j]表 ...