Codeforces Round #614(Div.2)

A. ConneR and the A.R.C. Markland-N

https://codeforces.com/contest/1293/problem/A
**题意:**t次输入。每次输入2行,
第一行输入n,s,k。n代表有几层楼,s代表你所在的位置,k代表不营业的餐厅的总层数。
第二行k次输入,代表每一个不营业的层数。

这个题搞了好久,想想是A题应该很简单几分钟能过的,最后用set过的,看了一下榜单普遍耗时有点久。思路就是向上向下找哪层是营业的,然后比较输出最小值,记得初始化的时候是INF

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
int main()
{
	ll q;cin>>q;
	while(q--){
		ll n,s,k;
		cin>>n>>s>>k;
		set<ll> b;
		for(ll i=0;i<k;i++){
			ll x;cin>>x;
			b.insert(x);
		}
		ll t=0;
		ll ans1=INF;ll ans2=INF;
		for(int i=0;i<=1005;i++){
			if(b.find(s+i)==end(b)&&s+i<=n){
				ans1=i;
				break;
			}
		}
		for(int i=0;i<=1005;i++){
			if(b.find(s-i)==end(b)&&s-i>=1){
				ans2=i;
				break;
			}
		}
		
		cout<<min(ans1,ans2)<<endl;
		b.clear();		
	}
}

B. JOE is on TV!

人均过的一眼签到题。。。呜呜呜被A关了好久才看的B,浪费时间扣分好多

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
int main()
{
	ll n;
	scanf("%lld",&n);
	double a=0;
	for(ll i=1;i<=n;i++){
		a+=(double)1/i;
	}
	printf("%.11f\n",a);
}

C. NEKO’s Maze Game

题意:有2*n的图形,然后你要从(1,1)走到(2,n)看能否走到。
q次操作,保障(1,1)和(2,n)不被操作到。每次操作输入坐标,如果该点之前没有被标记过,那么就被标记;反之取消标记.

这也是个签到题啦!!思路就是:比如你操作的是up行每次看和左下、正下、右下是否有铁索连环,若没有,就添加上几层铁索,若之前有,现在没了,就把铁索取消了。
最后特判是否有铁索ttrue,若有就No,反之Yes。

菜鸡蒟蒻如我把vis[3][maxn]开成了vis[2][maxn],导致我能过本地所有的样例,但是过不掉cf里的测评鸡,最后补题的时候也一度诧异,最后把vis的横数组开大一个单位就过了…

自己把自己坑了。哭唧唧。。。。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=2e5+5;
ll vis[3][maxn];
int main()
{
	ll n,q;cin>>n>>q;
	ll ttrue=0;
	while(q--){
		ll x;ll y;cin>>x>>y;
		vis[x][y]=1-vis[x][y];
		if(x==1&&vis[x][y]){
			if(vis[x+1][y+1]==1)
			{
				ttrue++;	
			}
			if(vis[x+1][y]==1)
			{
				ttrue++;	
			}
			if(vis[x+1][y-1]==1)
			{
				ttrue++;	
			}			
		}
		if(x==2&&vis[x][y]){
			if(vis[x-1][y+1]==1)
			{
				ttrue++;	
			}
			if(vis[x-1][y]==1)
			{
				ttrue++;	
			}
			if(vis[x-1][y-1]==1)
			{
				ttrue++;	
			}				
		}
		if(x==1&&vis[x][y]==0){
			if(vis[x+1][y+1]==1)
			{
				ttrue--;	
			}
			if(vis[x+1][y]==1)
			{
				ttrue--;	
			}
			if(vis[x+1][y-1]==1)
			{
				ttrue--;	
			}			
		}	
		if(x==2&&vis[x][y]==0){
			if(vis[x-1][y+1]==1)
			{
				ttrue--;	
			}
			if(vis[x-1][y]==1)
			{
				ttrue--;	
			}
			if(vis[x-1][y-1]==1)
			{
				ttrue--;	
			}				
		}
		if(ttrue) cout<<"No"<<endl;
		else cout<<"Yes"<<endl;			
	}
}

D. Aroma’s Search

题意:

有无数的点,第1个点的坐标为 (X1 , Y1) , 第2个点的坐标为 (X1 * ax + bx , Y1 * bx + by) , 第三个点的坐标为(X2 * ax + bx , Y2 * ay + by) …

你的初始位置为(SX , SY) , 你每秒可以向上、向下、向左、向右移动一格。问在 T 秒内,你最多可以到达几个点

分析:

题目给的 SX、SY、T 最大可取值都为 1e16 , 且点的个数是无限的,乍一看好像会有很多种情况,但因为ax , ay 都是大于等于2的,所以横坐标和纵坐标的增长速率都大于等于 2 的幂次

而除第一个点外当横坐标或纵坐标大于 1e17 时,这个点就肯定用不上了(因为此时这个点到距离它最近的点所用的时间必然 > T),那么算下来可以使用的点顶多也就60个.

所以我们可以枚举一个起点和终点(枚举的起点和终点可以相同)

若我们到达起点 i 所用的时间和到达终点 j 所用的时间小于等于T,则我们可以到达的点的个数为 abs(i−j)+1 (不理解可以把顶点的分布情况画出来),然后更新一下 ans

**Hint:**这里要十分十分注意别被爆ll!关于line25行为什么是2而不是乘ax,这里我解释一下:这里就是为了防止爆ll的,因为数不可能>1e17的,所以一个极限判断就是5e16-1,而2<=ax<=100,这里面的点都可以的,无所谓ax是多少;但倘若一个点>5e16-1的话(当然他必然小于1e17,比如1e17-1吧),他2就直接越界maxn,所以不行,但如果*100(即ax=100)的话,就是=1e19-100,这样直接爆ll了,所以不会存进去。一个极上限点是(9e18)。

总之,一旦有个点5e16-1<x<1e17的话,下一个点就不存在插入到vec里的。

这里pair<ll,ll>可以学学

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a) memset(a,0,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const ll maxn=1e17;
vector<pair<ll,ll>> vec;
ll dis(ll x1,ll y1,ll x2,ll y2){
	return abs(x1-x2)+abs(y1-y2);
}
int main()
{
	ll x0,y0,ax,ay,bx,by;
	cin>>x0>>y0>>ax>>ay>>bx>>by;
	vec.push_back(make_pair(x0,y0));
	ll xs,ys,t;
	cin>>xs>>ys>>t;
	while(true){
		ll x,y,len=vec.size()-1;
		if(vec[len].first*2+bx<maxn&&vec[len].second*2+by<maxn){
			x=vec[len].first*ax+bx;
			y=vec[len].second*ay+by;
		}else{
			break;
		}
		vec.push_back(make_pair(x,y));
	}
	ll ans=0;
	for(ll i=0;i<vec.size();i++){
		for(ll j=0;j<vec.size();j++){
			if(dis(xs,ys,vec[i].first,vec[i].second)+dis(vec[i].first,vec[i].second,vec[j].first,vec[j].second)<=t){
				ans=max(ans,abs(i-j)+1);
			}
		}
	}
	cout<<ans<<endl;
}

总结:啊啊啊好菜啊好久没打cf手生了又掉分了。。前段时间准备期末考试+旅游打完新生赛后一个月基本没碰ACM于是又被队友爆踩了。。。加油加油加油

发布了71 篇原创文章 · 获赞 5 · 访问量 3388

猜你喜欢

转载自blog.csdn.net/Rainfoo/article/details/104051234