1.4依旧是暴力。有些题目很典型。
Packing Rectangles
此题至今没过,其实是我感觉比较麻烦也没什么清晰的思路所以没写。以后再补充。
The Clocks
这个题很好,是经典的BFS+判重,我狂WA,TLE,RE了N遍,总算是学会了隐式图遍历。
如果某个钟表状态在之前出现过那么就不需要再加入到队列中了。由于不会哈希所以开了个9维数组判重。另外要开一个数组保存路径。
/*
ID:kkkwjx1
LANG: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:kkkwjx1
LANG: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:kkkwjx1
LANG: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;
}