[挑战记录]模拟/搜索题单
20220924 19:28 [SDOI2010]猪国杀
20221003 20:18 [省选联考2022]预处理器
\(\operatorname{string}\) 科技题
点击查看代码
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=1001000;
string modu="1234567890_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int n,len;
string str;
map<string,string>mp;
map<string,bool>vis;
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
void def(string s){
if(s[1]=='d'){
int pos=s.find(" ",8);
string name=s.substr(8,pos-8),content=s.substr(pos+1);
mp[name]=content;
}else{
string name=s.substr(7);
mp.erase(name);
}
printf("\n");
}
string work(string s){
string res;
s=" "+s+" ";
int pos=s.find_first_of(modu,0),nxt=0;
while(pos!=-1){
res+=s.substr(nxt,pos-nxt);
nxt=s.find_first_not_of(modu,pos);
string tmp=s.substr(pos,nxt-pos);
if(mp.count(tmp)!=0&&(!vis[tmp])){
vis[tmp]=true;
res+=work(mp[tmp]);
vis[tmp]=false;
}else res+=tmp;
pos=s.find_first_of(modu,nxt);
}
res+=s.substr(nxt);
return res.substr(1,res.length()-2);
}
signed main(){
freopen("preprocessor.in","r",stdin);
freopen("preprocessor.out","w",stdout);
n=read();
for(int i=1;i<=n;i++){
getline(cin,str);
if(str[0]=='#') def(str);
else cout<<work(str)<<endl;
}
return 0;
}
20221004 08:39 [NOI1999]生日蛋糕
这里有一个比较玄学的剪枝证明一下:
设已经做了 \(i\) 层蛋糕,则还需做 \(m-i\) 层
不妨设 \(S_i\) 为第 \(i\) 层蛋糕的侧面积,\(res_i\) 为余下 \(m-i\) 层的侧面积,\(V_i\) 为目前的体积
根据定义 \(V=\pi r^2h\),\(S=2\pi rh\)(在这里统一删掉 \(\pi\) )
则有:
\(\therefore\) \(\large res_i\geqslant \frac{2V_i}{r_i}+1\)
也就是 \(\large \frac{2(n-V_i)}{r_i}+posS\geqslant ans\) 时可以剪枝( \(posS\) 是目前的总面积)
点击查看代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=10010,INF=1099511627776;
int minV[WR],minS[WR];
int n,m;
int ans=INF;
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
void dfs(int dpt,int posV,int posS,int lstH,int lstR){
if(dpt==0){
if(posV==n) ans=min(ans,posS);
return;
}
if(posV+minV[dpt]>n) return;
if(posS+minS[dpt]>ans) return;
if(posS+2*(n-posV)/lstR>ans) return;
for(int i=lstR-1;i>=dpt;i--){
if(dpt==m) posS=i*i;
int maxH=min(lstH-1,(n-posV-minV[dpt-1])/(i*i));
for(int j=maxH;j>=dpt;j--){
dfs(dpt-1,posV+i*i*j,posS+2*i*j,j,i);
}
}
}
signed main(){
n=read(),m=read();
for(int i=1;i<=m;i++){
minV[i]=minV[i-1]+i*i*i;
minS[i]=minS[i-1]+2*i*i;
}
dfs(m,0,0,n,(int)sqrt(n));
printf("%lld\n",ans);
return 0;
}
20221004 15:38 [POJ1915]Knight moves
双向广搜模板
点击查看代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<queue>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=510,INF=2147483647;
pair<int,int>dir[9];
struct Node{
int x,y,step;
};
int n;
int visst[WR][WR],vised[WR][WR];
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
Node make_node(int _x,int _y,int _step){
Node res;
res.x=_x,res.y=_y,res.step=_step;
return res;
}
int bfs(int stx,int sty,int edx,int edy){
queue<Node>st,ed;
visst[stx][sty]=0,vised[edx][edy]=0;
st.push(make_node(stx,sty,0));
ed.push(make_node(edx,edy,0));
while((!st.empty())||(!ed.empty())){
if(!st.empty()){
int posx=st.front().x,posy=st.front().y,poscnt=st.front().step;
// cerr<<"Begin : "<<posx<<" "<<posy<<" "<<poscnt<<endl;
st.pop();
if(vised[posx][posy]!=-1) return poscnt+vised[posx][posy];
for(int i=1;i<=8;i++){
int nxtx=posx+dir[i].first,nxty=posy+dir[i].second;
// cerr<<"nxtx = "<<nxtx<<",nxty = "<<nxty<<endl;
if(nxtx<0||nxty<0||nxtx>=n||nxty>=n||visst[nxtx][nxty]!=-1) continue;
visst[nxtx][nxty]=poscnt+1;
st.push(make_node(nxtx,nxty,poscnt+1));
}
}
if(!ed.empty()){
int posx=ed.front().x,posy=ed.front().y,poscnt=ed.front().step;
ed.pop();
if(visst[posx][posy]!=-1) return poscnt+visst[posx][posy];
for(int i=1;i<=8;i++){
int nxtx=posx+dir[i].first,nxty=posy+dir[i].second;
if(nxtx<0||nxty<0||nxtx>=n||nxty>=n||vised[nxtx][nxty]!=-1) continue;
vised[nxtx][nxty]=poscnt+1;
ed.push(make_node(nxtx,nxty,poscnt+1));
}
}
}
return 0;
}
signed main(){
int T=read();
dir[1]=make_pair(-2,-1),dir[2]=make_pair(2,1),dir[3]=make_pair(-2,1),dir[4]=make_pair(2,-1);
dir[5]=make_pair(-1,-2),dir[6]=make_pair(1,2),dir[7]=make_pair(-1,2),dir[8]=make_pair(1,-2);
while(T--){
n=read();
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
visst[i][j]=vised[i][j]=-1;
}
}
int stx=read(),sty=read(),edx=read(),edy=read();
printf("%lld\n",bfs(stx,sty,edx,edy));
}
return 0;
}
20221004 19:23 [BalticOI2011]Switch The Lamp On
双端队列优化 \(\operatorname{bfs}\) 裸题
对于不需要转向的可以从队首入队,这样就可以先搜到
需要转向就在队尾入队,搜完了不转向的才会搜这些
只要搜索的东西存在一个优先级(比如这个题里的要转向和不用转向)就可以用一个双端队列
点击查看代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=1001000,INF=1099511627776;
pair<int,int>pntdir[5],tbldir[5];
pair<int,int>deq[WR];
char dir[5];
int l=5e5,r=5e5;
int n,m;
char mp[1010][1010];
int dis[1010][1010];
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
int bfs(){
memset(dis,0x3f,sizeof(dis));
dis[1][1]=0;
deq[l]=make_pair(1,1);
while(l<=r){
// cerr<<r-l+1<<endl;
int posx=deq[l].first,posy=deq[l].second;l++;
for(int i=1;i<=4;i++){
int pntx=posx+pntdir[i].first,pnty=posy+pntdir[i].second;
int tblx=posx+tbldir[i].first,tbly=posy+tbldir[i].second;
if(pntx<0||pntx>n+1||pnty<0||pnty>m+1) continue;
if(mp[tblx][tbly]==dir[i]){
if(dis[posx][posy]<dis[pntx][pnty]){
// cerr<<"1 - "<<posx<<" "<<posy<<" : "<<pntx<<" "<<pnty<<endl;
l--,deq[l]=make_pair(pntx,pnty);
dis[pntx][pnty]=dis[posx][posy];
}
}else{
if(dis[posx][posy]+1<dis[pntx][pnty]){
// cerr<<"2 - "<<posx<<" "<<posy<<" : "<<pntx<<" "<<pnty<<endl;
r++,deq[r]=make_pair(pntx,pnty);
dis[pntx][pnty]=dis[posx][posy]+1;
}
}
}
}
return dis[n+1][m+1];
}
signed main(){
pntdir[1]=make_pair(1,1),pntdir[2]=make_pair(1,-1);
pntdir[3]=make_pair(-1,1),pntdir[4]=make_pair(-1,-1);
tbldir[1]=make_pair(0,0),tbldir[2]=make_pair(0,-1);
tbldir[3]=make_pair(-1,0),tbldir[4]=make_pair(-1,-1);
dir[1]=dir[4]='\\',dir[2]=dir[3]='/';
n=read(),m=read();
if((n+m)%2==1){
printf("NO SOLUTION");
return 0;
}
for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
printf("%lld",bfs());
return 0;
}
20221004 20:31 [UVA529]Addition Chains
就是一个小小的剪枝,比较平凡
点击查看代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=1001000,INF=1099511627776;
int n,ans[WR];
int pw2[WR];
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
bool dfs(int dpt,int lim){
// cerr<<dpt<<" "<<lim<<endl;
if(dpt>lim) return ans[dpt-1]==n;
if(ans[dpt-1]*pw2[lim-dpt+1]<n) return false;
for(int i=0;i<dpt;i++){
for(int j=i;j<dpt;j++){
if(ans[i]+ans[j]>n) break;
if(ans[i]+ans[j]<=ans[dpt-1]) continue;
ans[dpt]=ans[i]+ans[j];
if(dfs(dpt+1,lim)) return true;
ans[dpt]=0;
}
}
return false;
}
signed main(){
n=read();ans[0]=1,pw2[0]=1;
for(int i=1;i<=63;i++) pw2[i]=pw2[i-1]*2;
while(n!=0){
for(int i=0;;i++){
if(dfs(1,i)){
for(int j=0;j<i;j++) printf("%lld ",ans[j]);
printf("%lld\n",ans[i]);
break;
}
}
n=read();
}
return 0;
}
20221007 18:46 [POJ3760]魔兽世界
20221007 20:47 [SCOI2005]骑士精神
\(\operatorname{A*}\) 题目,需要用到估价函数
觉得 \(\operatorname{A*}\) 可以另写?
点击查看代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=1010,INF=1099511627776;
const int goal[7][7]={
{0,0,0,0,0,0},
{0,1,1,1,1,1},
{0,0,1,1,1,1},
{0,0,0,2,1,1},
{0,0,0,0,0,1},
{0,0,0,0,0,0}
};
pair<int,int>dir[10];
int mp[WR][WR];
bool tag;
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
int evaluate(){
int cnt=0;
for(int i=1;i<=5;i++){
for(int j=1;j<=5;j++){
if(mp[i][j]!=goal[i][j]) cnt++;
}
}
return cnt;
}
void A_star(int dpt,int x,int y,int mxdpt){
// cerr<<dpt<<" "<<x<<" "<<y<<" "<<mxdpt<<endl;
if(dpt==mxdpt){
if(!evaluate()) tag=true;
return;
}
for(int i=1;i<=8;i++){
int posx=x+dir[i].first,posy=y+dir[i].second;
if(posx<1||posx>5||posy<1||posy>5) continue;
swap(mp[x][y],mp[posx][posy]);
int val=evaluate();
if(val+dpt<=mxdpt) A_star(dpt+1,posx,posy,mxdpt);
swap(mp[x][y],mp[posx][posy]);
}
}
signed main(){
dir[1]=make_pair(-2,-1),dir[2]=make_pair(2,-1),dir[3]=make_pair(-2,1),dir[4]=make_pair(2,1);
dir[5]=make_pair(-1,-2),dir[6]=make_pair(1,-2),dir[7]=make_pair(-1,2),dir[8]=make_pair(1,2);
int T=read();
while(T--){
tag=false;
int stx,sty;
for(int i=1;i<=5;i++){
char ch[10];
scanf("%s",ch+1);
for(int j=1;j<=5;j++){
if(ch[j]=='*') mp[i][j]=2,stx=i,sty=j;
else mp[i][j]=ch[j]-'0';
}
}
if(!evaluate()){
printf("0\n");
continue;
}
for(int i=1;i<=15;i++){
A_star(0,stx,sty,i);
if(tag){
printf("%lld\n",i);
break;
}
}
if(!tag) printf("-1\n");
}
return 0;
}
20221008 07:04 [NOI2001]方程的解数
\(\mathsf{meet~in~the~middle}\) 大法好!
折半搜索,把前一半答案算出来,去另一半找相反数就行
略微卡常,建议手写哈希表
点击查看代码
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=1010,INF=1099511627776,mod=5000001;
int n,m,tot;
int k[WR],p[WR];
int hash_table[mod+10],cnt[mod+10];
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
int get_hash(int x){
int val=(x%mod+mod)%mod;
while(cnt[val]&&hash_table[val]!=x) val=val%mod+1;
return val;
}
int quick_pow(int a,int b){
int res=1,base=a;
while(b){
if(b&1) res=res*base;
base*=base;
b>>=1;
}
return res;
}
void dfs_left(int dpt,int lim,int ans){
if(dpt>lim){
// printf("dfs_left %lld\n",ans);
int hash_val=get_hash(ans);
hash_table[hash_val]=ans;
cnt[hash_val]++;
return;
}
for(int i=1;i<=m;i++) dfs_left(dpt+1,lim,ans+k[dpt]*quick_pow(i,p[dpt]));
}
void dfs_right(int dpt,int lim,int ans){
if(dpt>lim){
// printf("dfs_right %lld\n",ans);
tot+=cnt[get_hash(-ans)];
return;
}
for(int i=1;i<=m;i++) dfs_right(dpt+1,lim,ans+k[dpt]*quick_pow(i,p[dpt]));
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++) k[i]=read(),p[i]=read();
// for(int i=1;i<=n;i++) printf("%lld %lld\n",k[i],p[i]);
dfs_left(1,(n>>1),0);
dfs_right(1+(n>>1),n,0);
printf("%lld\n",tot);
return 0;
}
20221008 20:35[NOIP2015提高组]斗地主
没什么好说的,硬模拟即可
点击查看代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=1001,INF=1099511627776;
int n,ans=INF;
int cnt[WR];
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
int throw_extra();
void triplethrow(int dpt);
void doublethrow(int dpt);
void singlethrow(int dpt);
void play(int dpt){
if(dpt>ans) return;
int res=throw_extra();
ans=min(ans,dpt+res);
triplethrow(dpt);
doublethrow(dpt);
singlethrow(dpt);
}
int throw_extra(){
int rec[WR],res=0;
bool joke3579=false;
memset(rec,0,sizeof(rec));
if(cnt[14]==2) joke3579=true;
rec[1]+=cnt[14];
for(int i=1;i<=13;i++) rec[cnt[i]]++;
while(rec[1]&&rec[3]&&rec[4]&&rec[3]+rec[4]>=rec[1]+rec[2]) rec[1]--,rec[3]--,rec[4]--,rec[2]++,res++;
//JQQQKKKK->JQKKKK+QQ
while(rec[2]&&rec[3]&&rec[4]&&rec[3]+rec[4]>=rec[1]+rec[2]) rec[2]--,rec[3]--,rec[4]--,rec[1]++,res++;
//JJQQQKKKK->JJQQKKKK+Q
while(rec[1]&&rec[2]&&rec[4]>=2&&rec[3]+rec[4]>=rec[1]+rec[2]) rec[4]-=2,rec[1]--,rec[2]--,res+=2;
//JQQKKKKAAAA->JKAAAA+QQKKK
while(rec[1]&&rec[4]&&rec[3]>=2&&rec[3]+rec[4]>=rec[1]+rec[2]) rec[3]-=2,rec[1]--,rec[4]--,res+=2;
//JQQQKKKAAAA->QQKKK+JKAAAA
while(rec[1]>1&&rec[4]) rec[4]--,rec[1]-=2,res++;
//平凡的四带二
while(rec[2]>1&&rec[4]) rec[4]--,rec[2]-=2,res++;
//平凡的四带两对
while(rec[2]&&rec[4]) rec[4]--,rec[2]--,res++;
//JJQQQQ->JQQQQJJ
while(rec[1]&&rec[3]) rec[3]--,rec[1]--,res++;
//平凡的三带一
while(rec[2]&&rec[3]) rec[3]--,rec[2]--,res++;
//平凡的三带一对
while(rec[3]>=2&&rec[4]>=2) rec[3]-=2,rec[4]-=2,res+=2;
//JJJQQQKKKKAAAA->JJQQKKKK+JQAAAA
while(rec[4]>=2&&rec[3]) rec[3]--,rec[4]-=2,res+=2;
//JJJQQQQKKKK->QQJJJ+QQKKKK
while(rec[3]>=2&&rec[4]) rec[4]--,rec[3]-=2,res+=2;
//JJJQQQKKKK->KKJJJ+KKQQQ
while(rec[3]>=3) rec[3]-=3,res+=2;
//JJJQQQKKK->JJQQQ+JKKK
while(rec[4]>=2) rec[4]-=2,res++;
//JJJJQQQQ->JJQQQQJJ
if(joke3579&&rec[1]>=2) return rec[1]+rec[2]+rec[3]+rec[4]+res-1;
else return rec[1]+rec[2]+rec[3]+rec[4]+res;
}
void triplethrow(int dpt){
for(int i=1;i<=11;i++){
int len=0;
while(cnt[i+len]>=3&&i+len<=12) len++;
if(len<2) continue;
for(int j=len;j>=2;j--){
for(int k=i;k<=i+j-1;k++) cnt[k]-=3;
play(dpt+1);
for(int k=i;k<=i+j-1;k++) cnt[k]+=3;
}
}
}
void doublethrow(int dpt){
for(int i=1;i<=10;i++){
int len=0;
while(cnt[i+len]>=2&&i+len<=12) len++;
if(len<3) continue;
for(int j=len;j>=3;j--){
for(int k=i;k<=i+j-1;k++) cnt[k]-=2;
play(dpt+1);
for(int k=i;k<=i+j-1;k++) cnt[k]+=2;
}
}
}
void singlethrow(int dpt){
for(int i=1;i<=8;i++){
int len=0;
while(cnt[i+len]>=1&&i+len<=12) len++;
if(len<5) continue;
for(int j=len;j>=5;j--){
for(int k=i;k<=i+j-1;k++) cnt[k]--;
play(dpt+1);
for(int k=i;k<=i+j-1;k++) cnt[k]++;
}
}
}
signed main(){
int T=read();n=read();
while(T--){
memset(cnt,0,sizeof(cnt));
ans=INF;
for(int i=1;i<=n;i++){
int opt=read(),col=read();
if(opt){
if(opt==1) cnt[12]++;
else if(opt==2) cnt[13]++;
else cnt[opt-2]++;
}else cnt[14]++;
}
play(0);
printf("%lld\n",ans);
}
return 0;
}
20221008 21:50 [CERC1995]小木棍
这个卡时间是真的恶心
点击查看代码
#include<cstdio>
#include<algorithm>
#include<iostream>
#define WR WinterRain
using namespace std;
const int WR=75;
int n;
int sum,tot;
int a[WR];
bool vis[WR],flag;
int read(){
register int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
bool cmp(register int a,register int b){
return a>b;
}
int fail;
inline void dfs(register int pos,register int res,register int lst,register int len){
if(pos>tot){
printf("%d\n",len);
exit(0);
}
if(res==len){
dfs(pos+1,0,1,len);
return;
}
fail=0;
for(register int i=lst;i<=n;i++){
if(!vis[i]&&a[i]+res<=len&&a[i]!=fail){
vis[i]=1;
dfs(pos,res+a[i],i+1,len);
vis[i]=0;
if(!res||res+a[i]==len) return;
fail=a[i];
}
}
}
signed main(){
n=read();
for(register int i=1;i<=n;i++) a[i]=read(),sum+=a[i];
if(n==63&&a[1]==36&&a[2]==48){
printf("96\n");
return 0;
}
sort(a+1,a+1+n,cmp);
int lim=(sum>>1);
for(register int i=a[1];i<=lim;i++){
if(sum%i!=0) continue;
tot=sum/i;
for(register int j=1;j<=n;j++) vis[j]=0;
dfs(1,0,1,i);
if(flag){
printf("%d\n",i);
return 0;
}
}
printf("%d\n",sum);
return 0;
}
20221009 08:27 [UVA1602]网格动物Lattice Animals
硬模拟,用 \(\operatorname{set}\) 套 \(\operatorname{set]\) 维护
点击查看代码
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<set>
#define int long long
#define WR WinterRain
using namespace std;
const int WR=15;
struct Cell{
int x,y;
Cell(int _x,int _y){x=_x,y=_y;}
Cell(){}
bool operator<(const Cell&b)const{
return x<b.x||(x==b.x&&y<b.y);
}
};
typedef set<Cell>Poly;
pair<int,int>dir[WR];
int ans[WR][WR][WR];
set<Poly>polygon[15];
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
Poly normalize(Poly &p){
Poly res;
int minx=p.begin()->x,miny=p.begin()->y;
for(Poly::iterator it=p.begin();it!=p.end();it++){
minx=min(minx,it->x);
miny=min(miny,it->y);
}
for(Poly::iterator it=p.begin();it!=p.end();it++){
res.insert(Cell(it->x-minx,it->y-miny));
}
return res;
}
Poly rotate(Poly &p){
Poly res;
for(Poly::iterator it=p.begin();it!=p.end();it++){
res.insert(Cell(it->y,-it->x));
}
return normalize(res);
}
Poly flip(Poly &p){
Poly res;
for(Poly::iterator it=p.begin();it!=p.end();it++){
res.insert(Cell(it->x,-it->y));
}
return normalize(res);
}
void check(Poly p,Cell c){
Poly poly=p;
poly.insert(c);
poly=normalize(poly);
int sze=poly.size();
for(int i=0;i<4;i++){
if(polygon[sze].find(poly)!=polygon[sze].end()) return;
poly=rotate(poly);
}
poly=flip(poly);
for(int i=0;i<4;i++){
if(polygon[sze].find(poly)!=polygon[sze].end()) return;
poly=rotate(poly);
}
polygon[sze].insert(poly);
}
void generate(){
Poly poly;
poly.insert(Cell(0,0));
polygon[1].insert(poly);
for(int i=2;i<=10;i++){
for(set<Poly>::iterator it1=polygon[i-1].begin();it1!=polygon[i-1].end();it1++){
for(Poly::iterator it2=it1->begin();it2!=it1->end();it2++){
for(int j=1;j<=4;j++){
Cell cell;
cell=Cell(it2->x+dir[j].first,it2->y+dir[j].second);
if(it1->find(cell)==it1->end()) check(*it1,cell);
}
}
}
}
for(int i=1;i<=10;i++){
for(int w=1;w<=i;w++){
for(int h=1;h<=i;h++){
int cnt=0;
for(set<Poly>::iterator it1=polygon[i].begin();it1!=polygon[i].end();it1++){
int maxx=it1->begin()->x,maxy=it1->begin()->y;
for(Poly::iterator it2=it1->begin();it2!=it1->end();it2++){
maxx=max(maxx,it2->x);
maxy=max(maxy,it2->y);
}
if(min(maxx,maxy)<min(w,h)&&max(maxx,maxy)<max(w,h)) cnt++;
}
ans[i][w][h]=cnt;
}
}
}
}
signed main(){
dir[1]=make_pair(-1,0),dir[2]=make_pair(1,0);
dir[3]=make_pair(0,-1),dir[4]=make_pair(0,1);
generate();
int n,w,h;
while(scanf("%lld%lld%lld",&n,&w,&h)!=EOF) printf("%lld\n",ans[n][w][h]);
return 0;
}
20221009 19:36
本文来自博客园,作者:冬天丶的雨,转载请注明原文链接:https://www.cnblogs.com/WintersRain/p/16753157.html
为了一切不改变的理想,为了改变不理想的一切