因为过两天就是CCPC的原因,所以我们队决定模拟一下现场,也就是三个人只能在一台电脑上敲代码,其他两台只能用于读题和看代码,发现确实比三台机子要困难很多。
就像今天一样,我和一个队友在找代码问题,然后另一位队友对另外一题有了思路,这个时候我们只能复制代码到另外一台机子上看,也就是说不能修改了,也就不知道某个地方改了后是不是就正确了。
这种团队的配合还是得多比赛才能练出来的。
80 Days
题意: n个点成环,初始值mo,走到一个点+ai(可能小于0),去下一个点-bi(大于0),任何时候值都不能小于0,求哪个点为起点时可能走完一圈
说来惭愧,就是一个for循环的事情,分要写成前缀和,还写错了。最后i=n+1写出i=i+1又WA了一发。。。
#include<stdio.h>
using namespace std;
#define LL long long
const int N=1e6+5;
LL ab[2*N],a[2*N];
LL mo;
int ans;
int main(){
int t;scanf("%d",&t);
while(t--){
int n;scanf("%d%lld",&n,&mo);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++){
LL tmp;
scanf("%lld",&tmp);
ab[i]=a[i]-tmp;
}
for(int i=n+1;i<=2*n;i++){
a[i]=a[i-n];
ab[i]=ab[i-n];
}
int l=1,r=1;
LL now=mo+ab[1];
while(now<0&&l<=n){
l++,r++;
now=mo+ab[l];
}
if(l==n+1){printf("-1\n");continue; }
while(1){
while(now>=0&&r<l+n-1){
r++;
now+=ab[r];
}
if(now>=0&&r==l+n-1){printf("%d\n",l);break;}
while(now<0&&l<r){
l++;
now-=ab[l-1];
}
while(l==r&&now<0&&l<=n){
now-=ab[l];
l++,r++;
now+=ab[l];
}
if(l>n){printf("-1\n");break; }
}
}
}
Saving Tang Monk II
队友写的直接上代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int n,m,k,dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
ll ans;
char mp[105][105];
struct Node
{
int dis,x,y,num;
Node(){}
Node(int dis,int x,int y,int num) : dis(dis),x(x),y(y),num(num){}
bool operator < (const Node& rhs) const{
if(dis!=rhs.dis)
return dis > rhs.dis;
else return num>rhs.num;
}
};
ll dis[105][105][8];
bool vis[105][105][8];
int ck(int x,int y){
if(x<1||x>n||y<1||y>m) return 0;
return 1;
}
void Dijkstra(int stx,int sty,int enx,int eny){
priority_queue<Node> Q;
while(!Q.empty()) Q.pop();
Q.push(Node(0,stx,sty,0));
dis[stx][sty][0]=0;
while(!Q.empty()){
Node u = Q.top(); Q.pop();
if(vis[u.x][u.y][u.num]) continue;
vis[u.x][u.y][u.num] = 1;
//printf("x=%d y=%d dis=%d num=%d\n",u.x,u.y,u.dis,u.num);
for(int i=0;i<4;i++){
int dx=u.x+dir[i][0],dy=u.y+dir[i][1];
if(!ck(dx,dy)) continue;
if(mp[dx][dy]=='#'){
if(u.num==0) continue;
if(u.dis+2< dis[dx][dy][u.num-1]){
dis[dx][dy][u.num-1]=u.dis+2;
Q.push(Node(u.dis+2,dx,dy,u.num-1));
}
}
if(mp[dx][dy]=='.'||mp[dx][dy]=='S'||mp[dx][dy]=='T'){
if(u.dis+1< dis[dx][dy][u.num]){
dis[dx][dy][u.num]=u.dis+1;
Q.push(Node(u.dis+1,dx,dy,u.num));
}
}
if(mp[dx][dy]=='P'){
if(u.dis<dis[dx][dy][u.num]){
dis[dx][dy][u.num]=u.dis;
Q.push(Node(u.dis,dx,dy,u.num));
}
}
if(mp[dx][dy]=='B'){
if(u.dis+1<dis[dx][dy][u.num+1]){
dis[dx][dy][u.num+1]=u.dis+1;
Q.push(Node(u.dis+1,dx,dy,u.num+1));
}
}
}
}
}
int main(){
//printf("%lld\n",INF);
while(~scanf("%d%d",&n,&m)){
if(n==0&&m==0) break;
int stx,sty,enx,eny;
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
for(int j=1;j<=m;j++){
for(int k=0;k<=5;k++)
vis[i][j][k]=0,dis[i][j][k]=inf;
if(mp[i][j]=='S')
stx=i,sty=j;
if(mp[i][j]=='T')
enx=i,eny=j;
}
}
ans=inf;
Dijkstra(stx,sty,enx,eny);
for(int i=0;i<=5;i++){
ans=min(ans,dis[enx][eny][i]);
}
if(ans==inf) printf("-1\n");
else printf("%lld\n",ans);
}
return 0;
}
Tomb Raider
题意: 10个串每个串最长8,串在环上(可循环节:abc->bca->cab),问所有串的最长子序列
枚举最短串的所有子序列,然后用这个子序列去和其他串匹配,麻烦的是枚举最短串的子序列需要考虑所有循环节,而匹配的时候也要去匹配其他串的所有循环节,比赛的时候和队友一起敲了一个多小时
怕TLE所以加了一个hash,来判断当前子序列是否已经查询过,结果出来1ms,还是很优秀的
#include<bits/stdc++.h>
using namespace std;
#define LL long long
char s[15][20];
int len[15];
map<LL ,bool>vis;
int n,ans;
char anss[15];
int lensub;
char sub[15];
void deal(){
LL tt=0;
for(int i=1;i<=lensub;i++)tt=100*tt+sub[i];
if(vis.find(tt)!=vis.end())return;
vis[tt]=true;
for(int i=2;i<=n;i++){
int f=0;
for(int j=1;j<=len[i];j++){ int en=j+len[i]-1;
int ar=j-1;
for(int k=1;k<=lensub;k++){
ar++;
while(s[i][ar]!=sub[k]&&ar<=en)ar++;
if(ar>en)break;
else if(k==lensub)f=1;
}
if(f==1)break;
}
if(f==0)return;
}
if(lensub>ans){
// debug();
for(int i=1;i<=lensub;i++)
anss[i]=sub[i];
ans=lensub;return;
}
else if(lensub==ans){
bool sma=0;
for(int i=1;i<=lensub;i++){
if(anss[i]!=sub[i]){
if(anss[i]>sub[i]){
for(int j=1;j<=lensub;j++)anss[j]=sub[j];
}
break;
}
}
}
}
void dfs(int now,int en){
if(now==en+1){
if(lensub>0)deal();
return;
}
dfs(now+1,en);
sub[++lensub]=s[1][now];
dfs(now+1,en);
lensub--;
}
int main(){
while(~scanf("%d",&n)){
vis.clear();
ans=0;
int tmps=1;
for(int i=1;i<=n;i++){
scanf("%s",s[i]+1);
len[i]=strlen(s[i]+1);
if(len[i]<len[tmps]) tmps=i;
for(int j=1;j<=len[i]-1;j++)
s[i][j+len[i]]=s[i][j];
s[i][2*len[i]]='/0';
}
if(tmps!=1){
swap(s[1],s[tmps]);
swap(len[1],len[tmps]);
}
for(int i=1;i<=len[1];i++){
lensub=0;
dfs(i,i+len[1]-1);
}
if(ans==0)printf("0\n");
else anss[ans+1]='\0', printf("%s\n",anss+1);
}
return 0;
}