USACO Chapter1-Getting started Section 1.4

来源:互联网 发布:淘宝店家懒人软件 编辑:程序博客网 时间:2024/06/06 02:40

1.4依旧是暴力。有些题目很典型。

 

Packing Rectangles

此题至今没过,其实是我感觉比较麻烦也没什么清晰的思路所以没写。以后再补充。

 

The Clocks

这个题很好,是经典的BFS+判重,我狂WA,TLE,RE了N遍,总算是学会了隐式图遍历。

如果某个钟表状态在之前出现过那么就不需要再加入到队列中了。由于不会哈希所以开了个9维数组判重。另外要开一个数组保存路径。

/*ID:kkkwjx1LANG:C++TASK:clocks*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <string>using namespace std;struct Clocks{    int clo[10];    int id;};struct Path{    int id,pre,op;};void Move(int n,Clocks &p){    p.clo[n]+=3;    if(p.clo[n]>12) p.clo[n]=3;}void Change(int n,Clocks &p){    if(n==1)    {        Move(1,p);        Move(2,p);        Move(4,p);        Move(5,p);    }    else if(n==2)    {        Move(1,p);        Move(2,p);        Move(3,p);    }    else if(n==3)    {        Move(2,p);        Move(3,p);        Move(5,p);        Move(6,p);    }    else if(n==4)    {        Move(1,p);        Move(4,p);        Move(7,p);    }    else if(n==5)    {        Move(2,p);        Move(4,p);        Move(5,p);        Move(6,p);        Move(8,p);    }    else if(n==6)    {        Move(3,p);        Move(6,p);        Move(9,p);    }    else if(n==7)    {        Move(4,p);        Move(5,p);        Move(7,p);        Move(8,p);    }    else if(n==8)    {        Move(7,p);        Move(8,p);        Move(9,p);    }    else if(n==9)    {        Move(5,p);        Move(6,p);        Move(8,p);        Move(9,p);    }}bool Check(Clocks &p){    for(int i=1; i<=9; ++i)        if(p.clo[i]!=12) return false;    return true;}Path path[500000];int ans[100],pos=0;void Print_path(Path &p){    if(p.id==0) return;    Print_path(path[p.pre]);    ans[pos++]=p.op;}bool vis[4][4][4][4][4][4][4][4][4];int main(){    freopen("clocks.in","r",stdin);    freopen("clocks.out","w",stdout);    Clocks p;    for(int i=1; i<=9; ++i) scanf("%d",&p.clo[i]);    vis[p.clo[1]/3-1][p.clo[2]/3-1][p.clo[3]/3-1][p.clo[4]/3-1][p.clo[5]/3-1][p.clo[6]/3-1][p.clo[7]/3-1][p.clo[8]/3-1][p.clo[9]/3-1]=true;    queue<Clocks> q;    int _id=0;    p.id=_id;    path[_id].id=p.id;    path[_id++].pre=-1;    q.push(p);    bool ok=false;    while(!q.empty()&&!ok)    {        Clocks tmp=q.front();        q.pop();        for(int i=1; i<=9; ++i)        {            Clocks t=tmp;            Change(i,t);            if(vis[t.clo[1]/3-1][t.clo[2]/3-1][t.clo[3]/3-1][t.clo[4]/3-1][t.clo[5]/3-1][t.clo[6]/3-1][t.clo[7]/3-1][t.clo[8]/3-1][t.clo[9]/3-1])                continue;            else vis[t.clo[1]/3-1][t.clo[2]/3-1][t.clo[3]/3-1][t.clo[4]/3-1][t.clo[5]/3-1][t.clo[6]/3-1][t.clo[7]/3-1][t.clo[8]/3-1][t.clo[9]/3-1]=true;            t.id=_id;            path[_id].id=t.id;            path[_id].pre=tmp.id;            path[_id++].op=i;            if(Check(t))            {                ok=true;                break;            }            else q.push(t);        }    }    Print_path(path[_id-1]);    sort(ans,ans+pos);    for(int i=0; i<pos; ++i)        if(i==0) printf("%d",ans[i]);        else printf(" %d",ans[i]);    printf("\n");    return 0;}


Arithmetic Progressions

直接挨个算就行了。

/*ID:kkkwjx1LANG:C++TASK:ariprog*/#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;int main(){      freopen("ariprog.in","r",stdin);      freopen("ariprog.out","w",stdout);    int N,M;    scanf("%d%d",&N,&M);    bool bisq[255*255*2]= {false};    for(int i=0; i<=M; ++i)        for(int j=i; j<=M; ++j)            bisq[i*i+j*j]=true;    int note[255*255*2],n=0;    for(int i=0; i<=2*M*M; ++i)        if(bisq[i]) note[n++]=i;    bool ok=false;    for(int i=1; i<=2*M*M; ++i)    {        if((N-1)*i>2*M*M) break;        for(int j=0; j<n; ++j)        {            bool yes=true;            for(int k=0; k<N; ++k)            {                int val=note[j]+k*i;                if(!bisq[val])                {                    yes=false;                    break;                }            }            if(yes)            {                printf("%d %d\n",note[j],i);                ok=true;            }        }    }    if(!ok) puts("NONE");    return 0;}


Mother's Milk

隐式图遍历的经典的倒水问题。

/*ID:kkkwjx1LANG:C++TASK:milk3*/#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;struct State{    int x[5];};void Fill(int &a,int &b,int B){    if(a+b<=B)    {        b=a+b;        a=0;    }    else    {        a=a+b-B;        b=B;    }}bool vis[30][30][30];bool ans[30];int X[5];int main(){     freopen("milk3.in","r",stdin);     freopen("milk3.out","w",stdout);    scanf("%d%d%d",&X[1],&X[2],&X[3]);    State st;    st.x[1]=st.x[2]=0;    st.x[3]=X[3];    ans[st.x[3]]=true;    vis[st.x[1]][st.x[2]][st.x[3]]=true;    queue<State> q;    q.push(st);    int n=0;    while(!q.empty())    {        State tmp=q.front();        q.pop();        for(int i=1; i<=3; ++i)        {            if(!tmp.x[i]) continue;            for(int j=1; j<=3; ++j)            {                if(i==j) continue;                if(tmp.x[j]==X[j]) continue;                State t=tmp;                Fill(t.x[i],t.x[j],X[j]);                if(vis[t.x[1]][t.x[2]][t.x[3]]) continue;                else                {                    vis[t.x[1]][t.x[2]][t.x[3]]=true;                    if(!t.x[1]) ans[t.x[3]]=true;                    q.push(t);                }            }        }    }    bool fir=false;    for(int i=0; i<=20; ++i)        if(ans[i])        {            if(fir) printf(" %d",i);            else            {                fir=true;                printf("%d",i);            }        }    printf("\n");    return 0;}


 

原创粉丝点击