ACM/ICPC 2018亚洲区预选赛北京赛站网络赛

A
Saving Tang Monk II
k layers problem

#include <bits/stdc++.h>
using namespace std;
#define FORP(i,a,b) for(int i=a;i<=b;++i)
int n,m;
bool check(int x,int y){
    return x>=1&&x<=n&&y>=1&&y<=m;
}
struct node{
    int index,cost;
    node(int index,int cost):index(index),cost(cost){}
};
vector<node> v[102000];
char G[102][102];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int sx,sy,ex,ey;
int cal(int x,int y,int k){
    return (x-1)*m+y+k*m*n;
}
int dist[102000];
bool inq[102000];
void spfa(int x,int y){
	int p=cal(x,y,0);
	memset(dist,0x3f,sizeof(dist));
	memset(inq,0,sizeof(inq));
	inq[p]=1;
	dist[p]=0;
	queue<int> q;
	q.push(p);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		inq[u]=0;
		for(int i=0;i<v[u].size();++i){
			node emm=v[u][i];
			int to=emm.index;
			int c=emm.cost;
			if(dist[u]+c<dist[to]){
				dist[to]=dist[u]+c;
				if(!inq[to]){
					inq[to]=1;
					q.push(to);
				}
			}
		}
	}
	int ans=0x3f3f3f3f;
	for(int i=0;i<=5;i++){
		ans=min(ans,dist[cal(ex,ey,i)]);
	}
	printf("%d\n",ans==0x3f3f3f3f?-1:ans);
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    while(cin>>n>>m&&(n||m)){
		memset(G,0,sizeof(G));
		FORP(i,1,n){
			FORP(j,1,m){
				cin>>G[i][j];
				if(G[i][j]=='S'){
					sx=i;
					sy=j;
				}
				if(G[i][j]=='T'){
					ex=i;
					ey=j;
				}
			}
		}
		FORP(i,1,n*m*6){
			v[i].clear();
		}
		FORP(i,1,n){
			FORP(j,1,m){
				for(int q=0;q<=3;q++){
					int fx=dx[q]+i;
					int fy=dy[q]+j;
					if(check(fx,fy)){
						for(int k=0;k<=5;k++){
							if(G[fx][fy]=='#'){
								if(k){
									v[cal(i,j,k)].push_back(node(cal(fx,fy,k-1),2));
								}
							}
							else if(G[fx][fy]=='B'){
								if(k!=5) v[cal(i,j,k)].push_back(node(cal(fx,fy,k+1),1));
							}
							else if(G[fx][fy]=='P'){
								v[cal(i,j,k)].push_back(node(cal(fx,fy,k),0));
							}
							else{
								v[cal(i,j,k)].push_back(node(cal(fx,fy,k),1));
							}
						}
					}
				} 
			}
		}
		spfa(sx,sy);	   
    }
    return 0;
}

B
Tomb Raider
small dataset
brute force might be the best

#include <bits/stdc++.h>
using namespace std;
#define FORP(i,a,b) for(int i=a;i<=b;++i)
string s[20];
int n;
set<string> st;
set<string>::iterator It;
void solve(string a){
    int len=a.size();
    for(int i=0;i<(1<<len);++i){
	string temp;
	for(int j=0;j<len;j++){
	    if((i>>j)&1) temp+=a[j];
	}
	st.insert(temp);
    }
}
bool find(string a,string b){
    int pos=-1;
    for(int i=0;i<b.size();++i){
	pos=a.find(b[i],pos+1);
	if(pos==-1) return false;
    }
    return true;
}
bool check(string a){
    for(int i=2;i<=n;i++){
	string temp[20];
	for(int j=0;j<s[i].size();++j){
	    temp[j]=s[i].substr(j)+s[i].substr(0,j);
	}
	int flag=0;
	for(int j=0;j<s[i].size();++j){
	    if(find(temp[j],a)){
		flag=1;
		break;
	    }
	}
	if(!flag) return false;
    }
    return true;
}
int main(){
    while(cin>>n){
	FORP(i,1,n){
	    cin>>s[i];
	}
	st.clear();
	string temp[20];
	for(int i=0;i<s[1].size();i++){
	    temp[i]=s[1].substr(i)+s[1].substr(0,i);
	}
	for(int i=0;i<s[1].size();i++){
	    solve(temp[i]);
	}
	string ans;
	for(It=st.begin();It!=st.end();++It){
	    if(check(*It)&&(*It).size()>ans.size()){
		ans=*It;
	    }
	}
	if(ans.size()==0) cout<<0<<endl;
	else 	cout<<ans<<endl;
    }
    return 0;
}

80 Days
why run so fast

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll a[2002000];
ll b[2002000];
int main(){
    int T;
    cin>>T;
    while(T--){
	ll n,c;cin>>n>>c;
	for(int i=1;i<=n;i++){
	    cin>>a[i];
	}
	for(int i=1;i<=n;i++){
	    cin>>b[i];
	}
	int flag=0;
	for(int i=1;i<=n;i++){
	    ll now=c;
	    now+=a[i]-b[i];
	    if(now<0) continue;
	    int ok=0;
	    int cnt=1;
	    int index=i+1;
	    while(now>=0){
		index=index==n+1?1:index;
		now+=a[index]-b[index];
		if(now<0) break;
		++cnt;
		++index;
		if(cnt==n){
		    ok=1;
		    break;
		}
	    }
	    if(ok&&now>=0){
		cout<<i<<endl;
		flag=1;
		break;
	    }
	}
	if(!flag) puts("-1");
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值