【NOIP2017】Day2

来源:互联网 发布:伴奏制作软件 编辑:程序博客网 时间:2024/06/05 07:35

题目传送门(请点击开头目录)
http://blog.csdn.net/lhq_er/article/details/76693851

Solution

T1:乱搞题
T2:两两分组,meeting in middle,虽然我是二分,还把inv写错了(没模p)
T3:对于len=1可以bfs,len<=4其实也可以,因为不会碰到身体,len>4时我们考虑bfs时的vis在这里为什么不可以呢?因为蛇头在一个位置时身体会有不同的形状,这些是不同的状态,这启发了我们可以开第三维记录蛇的形状,这样对于每一个状态都是唯一的,其他照bfs

CODE

//T1;#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<cstring>using namespace std;const int MAXN=100010;char str[MAXN];bool flag[MAXN];bool solve(){    memset(flag,false,sizeof(flag));    int n=strlen(str);    int cnt_ac=0,cnt_aca=0,cnt_ca=0;    for (int i=0;i<n;i++)    {        if (flag[i]) continue;        if (str[i]=='A' && str[i+1]=='C')        {            cnt_ac++;            flag[i]=flag[i+1]=true;            if (str[i+2]=='A')                cnt_aca++,flag[i+2]=true;        }    }    for (int i=0;i<n;i++)    {        if (flag[i] || flag[i+1]) continue;        if (str[i]=='C' && str[i+1]=='A')            cnt_ca++;           }    if (cnt_ac==0) return false;    else if (cnt_ac==1 && cnt_ca==0) return false;    else if (cnt_ac>1 && cnt_ca==0 && cnt_aca==0) return false;    return true;}int main(){    freopen("ac.in","r",stdin);    freopen("ac.out","w",stdout);    while (scanf("%s",str)!=EOF)        if (solve()) printf("YES\n");        else printf("NO\n");        return 0;}
//T2;#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<cstring>using namespace std;#define ll long longconst int MAXN=1010,MAXM=MAXN*MAXN;ll a[5][MAXN];ll x[MAXM],y[MAXM],numx[MAXM],numy[MAXM];ll ans,n,p,m,cntx,cnty;ll exgcd(ll a,ll b,ll &x,ll &y){    if (b==0) {x=1;y=0;return a;}    ll d=exgcd(b,a%b,y,x);    y-=a/b*x;    return d;}ll inv(ll a,ll n){    ll x,y;    ll d=exgcd(a,n,x,y);    if (d>1) return -1;    else return (x%n+n)%n;}int main(){    freopen("huaji.in","r",stdin);    freopen("huaji.out","w",stdout);    scanf("%lld%lld",&n,&p);    for (ll i=1;i<=4;i++)        for (ll j=1;j<=n;j++)            scanf("%lld",&a[i][j]);    for (ll i=1;i<=n;i++)        for (ll j=1;j<=n;j++)        {            m++;            x[m]=a[1][i]*a[2][j]%p;            y[m]=a[3][i]*a[4][j]%p;                 }    sort(x+1,x+1+m);    sort(y+1,y+1+m);    x[0]=y[0]=-1;    for (ll i=1;i<=m;i++)    {        if (x[i]!=x[i-1])             x[++cntx]=x[i],numx[cntx]=1;        else ++numx[cntx];        if (y[i]!=y[i-1])             y[++cnty]=y[i],numy[cnty]=1;        else ++numy[cnty];    }    for (ll i=1;i<=cntx;i++)    {        ll j=inv(x[i],p);        if (j==-1) continue;        ll k=lower_bound(y+1,y+1+cnty,j)-y;        if (y[k]==j) ans+=numx[i]*numy[k];          }    printf("%lld\n",ans);    return 0;}
//T3;#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<cstring>#include<queue>#include<ctime>using namespace std;#define ll long longint n,m,L,k,step=-1;int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0},pow4[10];int change[20000][4];bool f[20000];bool flag[21][21][20000];bool stone[2011][2011];bool bo[100][100];struct snake{    int x[8],y[8],z,id;}s,news;queue<snake>Q;int calc_id(snake s){    int id=0;    for (int i=1;i<L;i++)    {        int cx=s.x[i]-s.x[i-1];        int cy=s.y[i]-s.y[i-1];        int j;        for (j=0;j<4;j++)            if (dx[j]==cx && dy[j]==cy) break;        id=id*4+j;          }    return id;}void solve(){    while (!Q.empty()) Q.pop();    s.id=calc_id(s);    Q.push(s);    flag[s.x[0]][s.y[0]][s.id]=true;    while (!Q.empty() && step==-1)    {        s=Q.front(); Q.pop();        for (int i=0;i<4;i++)        {            int x=s.x[0]+dx[i],y=s.y[0]+dy[i],z=s.z+1,id=change[s.id][i];            if (x<=0 || x>n || y<=0 || y>m || stone[x][y]) continue;            if (!f[id]) continue;            if (x==1 && y==1) {step=z; break;}            news.z=z; news.x[0]=x; news.y[0]=y; news.id=id;            if (flag[x][y][id]) continue;            Q.push(news); flag[x][y][id]=true;        }    }    cout<<step<<endl;}void bfs(){    while (!Q.empty()) Q.pop();    Q.push(s); stone[s.x[0]][s.y[0]]=true;    while (!Q.empty())    {        s=Q.front(); Q.pop();        for (int i=0;i<4;i++)        {            int x=s.x[0]+dx[i],y=s.y[0]+dy[i],z=s.z+1;            if (x<=0 || x>n || y<=0 || y>m || stone[x][y]) continue;            if (x==1 && y==1) step=z;            news.x[0]=x; news.y[0]=y; news.z=z;            Q.push(news);            stone[x][y]=true;         }    }    cout<<step<<endl;   }void prepare(){     pow4[0]=1;    for (int i=1;i<10;i++) pow4[i]=pow4[i-1]*4;    for (int i=0;i<pow4[L-1];i++)        for (int j=0;j<4;j++)            change[i][j]=i/4+(j+2)%4*pow4[L-2];    memset(f,true,sizeof(f));    for (int i=0;i<pow4[L-1];i++)    {        memset(bo,false,sizeof(bo));        int x=10,y=10;        bo[x][y]=true;        for (int j=L-1;j>=1;j--)        {            int t=i%pow4[j]/pow4[j-1];            x=x+dx[t]; y=y+dy[t];            if (bo[x][y]) {f[i]=false; break;}            bo[x][y]=true;                  }    }}int main(){    freopen("snake.in","r",stdin);    freopen("snake.out","w",stdout);    int T;    scanf("%d",&T);    while (T--)    {        step=-1;        memset(flag,false,sizeof(flag));        memset(stone,false,sizeof(stone));        scanf("%d%d%d",&n,&m,&L);        prepare();        for (int i=0;i<L;i++)            scanf("%d%d",&s.x[i],&s.y[i]);        s.z=0;        scanf("%d",&k);        for (int i=1;i<=k;i++)        {            int a,b;            scanf("%d%d",&a,&b);            stone[a][b]=true;        }        if (s.x[0]==1 && s.y[0]==1)         {            cout<<0<<endl;            continue;        }        if (L==1) bfs();        else solve();    }    return 0;}