昨天写了21年CCPC的女生赛,很庆幸自己的实力居然也能拿个牌子。一共写出来了六题,前面五题都还算是签到,妥妥手速场无疑了。废话不多说,开始讲解。
A. 公交线路
题意
小Q要坐公交,从站点x到y。公交车上有广播,但是小Q只能听见每一次广播站点的字数。你需要帮助小Q判定他是否坐反路线了。
思路
其实三个样例就已经对应了三种情况了。1.正确的 2.错误 3.不确定 ; 而出现第三种状况当且仅当存在以x为中心,左右两面念出来的字数是一样的。我们优先判定这种情况。然后在判断从x到y的各个站点的字数和小Q听到的一不一样就可以了。需要注意的是x和y的大小关系是不一定的。
代码
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include <iomanip>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Endl "\n"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2000007;
const int INF = 0x3f3f3f;
const int mod = 1e9 + 7;
const double pi = acos(-1);
inline ll read(){
ll x = 0, f = 1; char ch; ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,x,y,m;
bool flag;
int luxian[15],ting[15];
bool isok()
{
int u=m;
int l,r;
for(int i=1;i<=m;i++)
{
l=x-i,r=x+i;
if(luxian[l]==luxian[r])
{
continue;
}
else
{
return true;
}
}
return false;
}
void solve()
{
n=read(),x=read(),y=read();
for(int i=1;i<=n;i++)
{
luxian[i]=read();
}
m=read();
for(int i=1;i<=m;i++)
{
ting[i]=read();
}
if(!isok())
{
cout<<"Unsure"<<Endl;
}
else if(isok()&&x<y)
{
flag=1;
for(int i=1;i<=m;i++)
{
int j=x+i;
if(ting[i]==luxian[j])
{
continue;
}
else
{
flag=0;
break;
}
}
if(flag) cout<<"Right"<<Endl;
else cout<<"Wrong"<<Endl;
}
else
{
flag=1;
for(int i=1;i<=m;i++)
{
int j=x-i;
if(ting[i]==luxian[j])
{
continue;
}
else
{
flag=0;
break;
}
}
if(flag) cout<<"Right"<<Endl;
else cout<<"Wrong"<<Endl;
}
}
int main() {
//for(int T = read(); T; T--)
solve();
return 0;
}
D. 修建道路
题意
n个村庄,修n-1条双向道路,要求所有村庄都能互相到达。修路的花费是,如果要修从村庄i到j的路的话,那么花费是max{ak} k介于i和j之间。要求输出最少花费。
思路
区间越短,那么取到更大的数的概率也就越小。例如修村庄4到5的花费必然小于等于村庄4到6的花费。所以花费最少必然是从1到n按顺序串联起来:
那么答案就为连续相邻区间最大值的和。
代码
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include <iomanip>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Endl "\n"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2000007;
const int INF = 0x3f3f3f;
const int mod = 1e9 + 7;
const double pi = acos(-1);
inline ll read(){
ll x = 0, f = 1; char ch; ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll n,ans,x;
ll a[200005];
void solve()
{
ans=0;
n=read();
for(ll i=1;i<=n;i++)
{
a[i]=read();
if(i>=2)
{
x=max(a[i],a[i-1]);
ans+=x;
}
}
cout<<ans;
}
int main() {
//for(int T = read(); T; T--)
solve();
return 0;
}
G. 3G网络
题意
建立n个3G基站,每个基站覆盖面积是半径为R的圆。给定n,求所有基站覆盖面积/每个基站覆盖面积之和。
思路
题目给了一个很关键的提示:
当r趋向于正无穷时,每个基站的覆盖面积都是无限大的,那么必然所有的圆都会相互覆盖,所以最后所有基站的覆盖面积可以看成是一个基站的覆盖面积S,每个基站的覆盖面积之和则为nS,所以直接输出1/n即可。
代码
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include <iomanip>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Endl "\n"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2000007;
const int INF = 0x3f3f3f;
const int mod = 1e9 + 7;
const double pi = acos(-1);
inline ll read(){
ll x = 0, f = 1; char ch; ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
double n;
struct node{
int x;
int y;
}q[2005];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
q[i].x=read(),q[i].y=read();
}
double ans=1.0/n;
printf("%.15lf",ans);
}
int main() {
//for(int T = read(); T; T--)
solve();
return 0;
}
I. 驾驶卡丁车
题意
一道驾驶卡丁车的模拟+搜索题。有四个指令控制车头方向和车速,卡丁车可以向8个方向进行前进v步,直至出界、撞车、穿模。
思路
这道题在寒假集训的时候写过,我记得当时这题我写了特别特别久,怎么改都改不对。现在能轻松拿下来也算是进步了吧。
直接按照题意模拟即可。
首先卡丁车有两个状态参数一个是速度v,一个是车头朝向c。其次,拥有4种指令:
/* 车头朝向与c的值
2 1 8
3 7
4 5 6
*/
void l()
{
if(c==8)
c=1;
else c+=1;
}
void r()
{
if(c==1)
c=8;
else c-=1;
}
void u()
{
v+=1;
}
void d()
{
v=max(v-1,0);
}
利用bfs的知识来模拟卡丁车走的情况:
void rush()
{
int xt,yt;
xt=x,yt=y;
for(int i=1;i<=v;i++)
{
// cout<<"now"<<xt<<" "<<y<<Endl;
xt+=dist[c-1][0];
yt+=dist[c-1][1];
// cout<<"now dist[c-1][0]"<<dist[c-1][0]<<" "<<dist[c-1][1]<<Endl;
// cout<<xt<<" "<<yt<<Endl;
// cout<<"over"<<Endl;
if(!iscrash(xt,yt))
{
v=0;
cout<<"Crash! "<<x<<" "<<y<<Endl;
return ;
}
else
{
x=xt,y=yt;
}
}
cout<<x<<" "<<y<<Endl;
}
判定是否crash,有三种情况:1.撞到障碍物 2.出界 3.穿模
bool iscrash(int x,int y)
{
if(v==0)
return true;
else
{
// cout<<"---iscrash----"<<Endl;
// cout<<x<<" "<<y<<" "<<c<<Endl;
if(x<=0||x>n||y<=0||y>m)
{
// cout<<"here1"<<Endl;
return false;
}
else if(mp[x][y]=='#')
{
// cout<<"here2"<<Endl;
return false;
}
else if(c==8&&mp[x][y-1]=='#'&&mp[x+1][y]=='#')
{
// cout<<"here3"<<Endl;
return false;
}
else if(c==2&&mp[x][y+1]=='#'&&mp[x+1][y]=='#')
{
// cout<<"here4"<<Endl;
return false;
}
else if(c==4&&mp[x-1][y]=='#'&&mp[x][y+1]=='#')
{
// cout<<"here5"<<Endl;
return false;
}
else if(c==6&&mp[x][y-1]=='#'&&mp[x-1][y]=='#')
{
// cout<<"here6"<<Endl;
return false;
}
else return true;
}
}
至此,问题基本解决。
代码
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include <iomanip>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Endl "\n"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2000007;
const int INF = 0x3f3f3f;
const int mod = 1e9 + 7;
const double pi = acos(-1);
inline ll read(){
ll x = 0, f = 1; char ch; ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,q,x,y;
int v,c;
char mp[55][55];
string zl;
int dist[8][2]={{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1}};
void l()
{
if(c==8)
c=1;
else c+=1;
}
void r()
{
if(c==1)
c=8;
else c-=1;
}
void u()
{
v+=1;
}
void d()
{
v=max(v-1,0);
}
bool iscrash(int x,int y)
{
if(v==0)
return true;
else
{
// cout<<"---iscrash----"<<Endl;
// cout<<x<<" "<<y<<" "<<c<<Endl;
if(x<=0||x>n||y<=0||y>m)
{
// cout<<"here1"<<Endl;
return false;
}
else if(mp[x][y]=='#')
{
// cout<<"here2"<<Endl;
return false;
}
else if(c==8&&mp[x][y-1]=='#'&&mp[x+1][y]=='#')
{
// cout<<"here3"<<Endl;
return false;
}
else if(c==2&&mp[x][y+1]=='#'&&mp[x+1][y]=='#')
{
// cout<<"here4"<<Endl;
return false;
}
else if(c==4&&mp[x-1][y]=='#'&&mp[x][y+1]=='#')
{
// cout<<"here5"<<Endl;
return false;
}
else if(c==6&&mp[x][y-1]=='#'&&mp[x-1][y]=='#')
{
// cout<<"here6"<<Endl;
return false;
}
else return true;
}
}
void rush()
{
int xt,yt;
xt=x,yt=y;
for(int i=1;i<=v;i++)
{
// cout<<"now"<<xt<<" "<<y<<Endl;
xt+=dist[c-1][0];
yt+=dist[c-1][1];
// cout<<"now dist[c-1][0]"<<dist[c-1][0]<<" "<<dist[c-1][1]<<Endl;
// cout<<xt<<" "<<yt<<Endl;
// cout<<"over"<<Endl;
if(!iscrash(xt,yt))
{
v=0;
cout<<"Crash! "<<x<<" "<<y<<Endl;
return ;
}
else
{
x=xt,y=yt;
}
}
cout<<x<<" "<<y<<Endl;
}
void solve()
{
n=read(),m=read();
v=0,c=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>mp[i][j];
if(mp[i][j]=='*')
{
x=i;
y=j;
}
}
q=read();
cin>>zl;
for(int i=0;i<q;i++)
{
if(zl[i]=='L')
{
l();
}
else if(zl[i]=='R')
{
r();
}
else if(zl[i]=='U')
{
u();
}
else
{
d();
}
rush();
}
}
int main() {
//for(int T = read(); T; T--)
solve();
return 0;
}
K. 音乐游戏
题意
过于水的签到题了。
思路
直接统计-的个数即可。
代码
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include <iomanip>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Endl "\n"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2000007;
const int INF = 0x3f3f3f;
const int mod = 1e9 + 7;
const double pi = acos(-1);
inline ll read(){
ll x = 0, f = 1; char ch; ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n;
char s;
int ans;
void solve()
{
ans=0;
n=read();
for(int i=1;i<=n;i++)
{
getchar();
for(int j=1;j<=6;j++)
{
scanf("%c",&s);
if(s=='-')
{
ans++;
}
}
}
cout<<ans<<Endl;
}
int main() {
//for(int T = read(); T; T--)
solve();
return 0;
}