2017计蒜之道程序设计大赛初赛第三场题解
2017-05-22 17:11
267 查看
比赛链接
题目可以在比赛的题目列表中查看
在腾讯课堂的物理课上,进行了一个有趣的物理实验。
在一个长度为 LL 米的光滑轨道上,小车
A 在 00 时刻以1m/s 的速度从左端出发向右运动,小车
B 在 tt 时刻以 1m/s 的速度从右端出发向左运动,两个小车的质量相等。假设所有碰撞都是弹性碰撞,也就是当两个小车相向碰撞时,他们各自会以原来的速度向相反的方向运动;小车和轨道两端发生碰撞时,小车会以原速度向反方向运动。
试求出 TT 时刻的时候,两个小车相距多远。
输入格式
输入三个整数 L(1 \le L \le 1000),L(1≤L≤1000), t(0
\le t \le 1000),t(0≤t≤1000), T(t
\le T \le 1000)T(t≤T≤1000)。
输出格式
输出 TT 时刻两车之间的距离。
样例输入1
10 4 7
样例输出1
0
样例输入2
8 3 9
样例输出2
5
命题人:镇高红
碰撞其实可以视为相互穿越,那么两车其实可以视为没有任何相互影响,然后单独模拟即可。“两个小球相撞后沿相反方向走,就可以看成是两个小球互相瞅了一眼,谁都不理谁,擦肩而过。”
白书序言蚂蚁问题
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<fstream>
#include<string.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=10000;
int main()
{
int L,t,T;
while(cin>>L>>t>>T)
{
int time=0;
int p1=0,p2=L;
int d1=1,d2=-1;
while(time!=T)
{
time++;
bool flag1=false,flag2=false;
if(p1==0&&d1==-1)
{
d1=-d1;
p1=p1+d1;
flag1=true;
}
else if(p1==L&&d1==1)
{
d1=-d1;
p1=p1+d1;
flag1=true;
}
if(p2==0&&d2==-1&&time>t)
{
d2=-d2;
p2=p2+d2;
flag2=true;
}
else if(p2==L&&d2==1&&time>t)
{
d2=-d2;
p2=p2+d2;
flag2=true;
}
if(p1==p2&&time>t&&flag1==false)
{
d1=-d1;d2=-d2;
p1=p1+d1;
p2=p2+d2;
}
else if(p1+d1*(0.5)==p2+d2*(0.5)&&time>t&&flag1==false)
{
d1=-d1;d2=-d2;
}
else
{
if(flag1==false)p1=p1+d1;
if(time>t&&flag2==false)
p2=p2+d2;
}
//cout<<time<<": p1: "<<p1<<" "<<"p2: "<<p2<<" d1:"<<d1<<" "<<"d2: "<<d2<<endl;
}
cout<<abs(p1-p2)<<endl;
}
return 0;
}AC版本2:
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
int t,l,n;
int main()
{
cin>>l>>t>>n;
int x=n%(2*l);
if(x>l)x=2*l-x;
int y=(n-t)%(2*l);
if(y>l)y=2*l-y;
y=l-y;
if(x-y>0)cout<<x-y;
else cout<<y-x;
}
命题人:徐浩
可以采用二进制枚举的方式直接得到答案。
也没什么好说的,数据很小,只有20个人,暴力枚举,220种组合方式,在剪枝掉不可能出现的方式,也就是必须选择的村民没被选中的情况。我是在dfs的过程中的每一层,都保持对总战斗力sum动态维护;而不是每一次组合方式确定之后再单独算一遍这种组合方式的性价比。如果那样算应该会超时我猜。
假设答案为 ansans,构造函数 F=|E|
- ans \times k \times (2n-k)F=∣E∣−ans×k×(2n−k),当 ansans 过大时, F
\le 0F≤0;当 ansans 过小时,F>0F>0,所以我们可以二分这个 ansans。同时,我们观察到 ans
\times k \times (2n-k)ans×k×(2n−k) 可以写成 k^2ans-2nk
\times ansk2ans−2nk×ans,可以写成 \frac{k(k-1)}{2}\times
2ans - (2n-1)k \times ans2k(k−1)×2ans−(2n−1)k×ans,所以我们可以把每个权点看成 (2n-1)\times
ans(2n−1)×ans,边权都加上 2ans2ans。就变成了最基础的最大密度子图。
对于困难版本,我们继续优化最大密度子图的建图方式,具体可以参考胡伯涛的论文《最小割模型在信息学竞赛中的应用》。
题目可以在比赛的题目列表中查看
腾讯课堂的物理实验
在腾讯课堂的物理课上,进行了一个有趣的物理实验。在一个长度为 LL 米的光滑轨道上,小车
A 在 00 时刻以1m/s 的速度从左端出发向右运动,小车
B 在 tt 时刻以 1m/s 的速度从右端出发向左运动,两个小车的质量相等。假设所有碰撞都是弹性碰撞,也就是当两个小车相向碰撞时,他们各自会以原来的速度向相反的方向运动;小车和轨道两端发生碰撞时,小车会以原速度向反方向运动。
试求出 TT 时刻的时候,两个小车相距多远。
输入格式
输入三个整数 L(1 \le L \le 1000),L(1≤L≤1000), t(0
\le t \le 1000),t(0≤t≤1000), T(t
\le T \le 1000)T(t≤T≤1000)。
输出格式
输出 TT 时刻两车之间的距离。
样例输入1
10 4 7
样例输出1
0
样例输入2
8 3 9
样例输出2
5
命题人:镇高红
碰撞其实可以视为相互穿越,那么两车其实可以视为没有任何相互影响,然后单独模拟即可。“两个小球相撞后沿相反方向走,就可以看成是两个小球互相瞅了一眼,谁都不理谁,擦肩而过。”
白书序言蚂蚁问题
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<fstream>
#include<string.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=10000;
int main()
{
int L,t,T;
while(cin>>L>>t>>T)
{
int time=0;
int p1=0,p2=L;
int d1=1,d2=-1;
while(time!=T)
{
time++;
bool flag1=false,flag2=false;
if(p1==0&&d1==-1)
{
d1=-d1;
p1=p1+d1;
flag1=true;
}
else if(p1==L&&d1==1)
{
d1=-d1;
p1=p1+d1;
flag1=true;
}
if(p2==0&&d2==-1&&time>t)
{
d2=-d2;
p2=p2+d2;
flag2=true;
}
else if(p2==L&&d2==1&&time>t)
{
d2=-d2;
p2=p2+d2;
flag2=true;
}
if(p1==p2&&time>t&&flag1==false)
{
d1=-d1;d2=-d2;
p1=p1+d1;
p2=p2+d2;
}
else if(p1+d1*(0.5)==p2+d2*(0.5)&&time>t&&flag1==false)
{
d1=-d1;d2=-d2;
}
else
{
if(flag1==false)p1=p1+d1;
if(time>t&&flag2==false)
p2=p2+d2;
}
//cout<<time<<": p1: "<<p1<<" "<<"p2: "<<p2<<" d1:"<<d1<<" "<<"d2: "<<d2<<endl;
}
cout<<abs(p1-p2)<<endl;
}
return 0;
}AC版本2:
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
int t,l,n;
int main()
{
cin>>l>>t>>n;
int x=n%(2*l);
if(x>l)x=2*l-x;
int y=(n-t)%(2*l);
if(y>l)y=2*l-y;
y=l-y;
if(x-y>0)cout<<x-y;
else cout<<y-x;
}
腾讯狼人杀
命题人:徐浩
简单版本
可以采用二进制枚举的方式直接得到答案。
分析:
也没什么好说的,数据很小,只有20个人,暴力枚举,220种组合方式,在剪枝掉不可能出现的方式,也就是必须选择的村民没被选中的情况。我是在dfs的过程中的每一层,都保持对总战斗力sum动态维护;而不是每一次组合方式确定之后再单独算一遍这种组合方式的性价比。如果那样算应该会超时我猜。#include<iostream> #include<stdio.h> #include<string.h> using namespace std; int map[30][30]={0}; int vis[30]={0}; int in[30]={0}; int n,m; int a,b,w; int sum=0; int chose=0; double best=0; void dfs(int x)//决定第x个是不是选 { if(x==n+1) { double o=(double)(sum)/(double)(chose*(2*n-chose)); //cout<<o<<" "<<chose<<in[1]<<endl; if(best<o)best=o; return; } for(int i=0;i<=1;i++) { if(vis[x]==1&&i==0)continue; in[x]=i; if(in[x]==1) { for(int i=1;i<x;i++) { if(in[i]==1)sum+=map[i][x]; } chose++; } dfs(x+1); if(in[x]==1) { for(int i=1;i<x;i++) { if(in[i]==1)sum-=map[i][x]; } in[x]=0; chose--; } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&w); map[a][b]=w; map[b][a]=w; } int k=0;//有k个可供选择的人 for(int i=1;i<=n;i++) { scanf("%d",&a); if(a==1) { //k++; vis[i]=1; } } dfs(1); printf("%.4lf",best); }
中等版本
假设答案为 ansans,构造函数 F=|E|- ans \times k \times (2n-k)F=∣E∣−ans×k×(2n−k),当 ansans 过大时, F
\le 0F≤0;当 ansans 过小时,F>0F>0,所以我们可以二分这个 ansans。同时,我们观察到 ans
\times k \times (2n-k)ans×k×(2n−k) 可以写成 k^2ans-2nk
\times ansk2ans−2nk×ans,可以写成 \frac{k(k-1)}{2}\times
2ans - (2n-1)k \times ans2k(k−1)×2ans−(2n−1)k×ans,所以我们可以把每个权点看成 (2n-1)\times
ans(2n−1)×ans,边权都加上 2ans2ans。就变成了最基础的最大密度子图。
困难版本
对于困难版本,我们继续优化最大密度子图的建图方式,具体可以参考胡伯涛的论文《最小割模型在信息学竞赛中的应用》。
相关文章推荐
- 2017计蒜之道程序设计大赛初赛第四场题解
- 2017计蒜之道程序设计大赛初赛第五场
- 2017计蒜之道程序设计大赛初赛第六场题解
- 2017计蒜之道程序设计大赛初赛第一场题解
- 2017计蒜之道程序设计大赛初赛第五场
- 2017计蒜之道程序设计大赛初赛第五场题解
- 2017计蒜之道程序设计大赛初赛第二场题解
- 2017计蒜之道程序设计大赛复赛题解
- 计蒜之道 2017 程序设计大赛 - 计蒜客 复赛 D 百度地图导航 最短路、Dijkstra的拓展
- “中兴捧月”杯 校园赛事嘉年华 | 程序设计大赛(初赛) | 数字化婚姻尝试配对
- 计蒜之道 2017 程序设计大赛 - 计蒜客 复赛 F 腾讯消消乐 状态压缩dp、枚举+剪枝
- star.baidu.com程序设计大赛初赛、复赛题目
- 计蒜之道 2017 程序设计大赛 - 计蒜客 复赛 B Windows 画图 几何、平面、枚举
- AIX 程序设计大赛---AIX正方形问题
- 2008程序设计大赛
- AIX 程序设计大赛---AIX正方形问题
- 程序设计大赛—页面置换算法(LRU)
- 程序设计大赛--约瑟夫问题
- 程序设计大赛-留下的学生
- AIX 程序设计大赛---AIX正方形问题