Codeforces Round #224 (Div. 2)

5064 ワード

B:
if(b>=x) b=b-x
if(bb=b-x+w
実はbはずっとxを減らして、0より小さいならば、1回wをプラスします.また、wを加えるたびに必ずb−x+wが0より大きくなる.
では、二分してどのくらい時間tが過ぎたか、不等式b-t*x+k*w>0からkを求める.だからa-k回、つまりc++k回です.
c-t+k<=aと判定します.
code:
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  2013
#define ll long long
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a) memset(x,a,sizeof(x))
#define bit(st,i) ((1ll<<i)&st)
typedef pair<int,int> PI;
const int INF=0x3fffffff;
const int MOD   =1000003;
const double EPS=1e-7;


ll a,b,w,x,c;

bool check(ll t){
	ll dif=max(0ll,t*x-b);
	ll d=(dif+w-1)/w;
	return c-t+d<=a;
}

int main(){
	cin>>a>>b>>w>>x>>c;
	ll l=0,r=1ll<<62;
	while(l<r){
		ll mid=(l+r)>>1;
		if(!check(mid)) l=mid+1;
		else r=mid;
	}
	cout<<r<<endl;
	return 0;
}

C: 
n=1,n=2,n>=3の3種類に分けて議論すればよい.
code:
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  100010
#define ll long long
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a) memset(x,a,sizeof(x))
#define bit(st,i) ((1ll<<i)&st)
typedef pair<int,int> PI;
const int INF=0x3fffffff;
const int MOD   =1000003;
const double EPS=1e-7;

int a[N];

int main(){
	int n,d;
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	sort(a,a+n);
	if(n==1) puts("-1");
	else if(n==2){
		if(a[0]!=a[1]){
			d=a[1]-a[0];
			if(d%2==0) puts("3");
			else puts("2");
			printf("%d",a[0]-d);
			if(d%2==0) printf(" %d",a[0]+d/2);
			printf(" %d
",a[1]+d); }else{ puts("1"); printf("%d
",a[0]); } }else{ d=a[1]-a[0]; int x; for(int i=1;i<n;i++) d=min(d,a[i]-a[i-1]); int cnt=0; for(int i=1;i<n;i++) if(a[i]-a[i-1]!=d){ if(a[i]-a[i-1]==2*d) cnt++,x=a[i-1]+d; else{ puts("0"); return 0; } } if(cnt>1){ puts("0"); return 0; } if(cnt){ puts("1"); printf("%d
",x); return 0; } if(a[0]-d!=a[n-1]+d){ puts("2"); printf("%d %d
",a[0]-d,a[n-1]+d); }else{ puts("1"); printf("%d
",a[0]); } } return 0; }

D:
明らかに私たちは最も長いパスを要求して、記憶化して検索すればいいです.
次に、最長パスMaxの場合、答えは少なくとも2*Max-1(前から後へ最長パス)です.2つの最長パスが存在しない限り、ある時点で2つの駒は一緒にぶつからない.駒がぶつかるかどうかを判断するのは簡単です.各格子は一方向に歩くので、終点が同じであれば、必然的に2つの経路が重なる.だから検索するときにゴールを記録すればいいです.
code:
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

#define N  2013
#define ll long long
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a) memset(x,a,sizeof(x))
#define bit(st,i) ((1ll<<i)&st)
typedef pair<int,int> PI;
const int INF=0x3fffffff;
const int MOD   =1000003;
const double EPS=1e-7;
const int dx[]  = {-1, 1, 0, 0};
const int dy[]  = {0, 0, -1, 1};

char mp[N][N];
int n,m,dp[N][N],f[N][N];
int sx,sy;

int dir(char c){
	switch(c){
		case '^':return 0;
		case 'v':return 1;
		case '<':return 2;
		case '>':return 3;
	}
}

int dfs(int x,int y){
	if(dp[x][y]!=-1) return dp[x][y];
	dp[x][y]=1;
	f[x][y]=m*x+y;
	int d=dir(mp[x][y]);
	int xx=dx[d]+x;
	int yy=dy[d]+y;
	if(mp[xx][yy]!='#'){
		if(xx==sx && yy==sy){
			puts("-1");
			exit(0);
		}
		if(dp[x][y]<dfs(xx,yy)+1){
			dp[x][y]=dp[xx][yy]+1;
			f[x][y]=f[xx][yy];
		}
	}
	return dp[x][y];
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) scanf("%s",mp[i]);
	CLR(dp,-1);
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			if(mp[i][j]!='#' && dp[i][j]==-1){
				sx=i,sy=j;
			   	dfs(i,j);
			}
	int ans=0;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			if(mp[i][j]!='#') ans=max(ans,dp[i][j]);
	vector<int> d;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			if(dp[i][j]==ans) d.push_back(f[i][j]);
	sort(ALL(d));
	d.erase(unique(ALL(d)),d.end());
	ans*=2;
	if(d.size()==1) ans--;
	printf("%d
",ans); return 0; }