[挑战记录]模拟/搜索题单

20220924 19:28 [SDOI2010]猪国杀

另开了,SB题

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\)
则有:

\[\begin{aligned} 2V_i & =2\sum\limits_{j=i+1}^{m}r_{j}^2h_j \\ & = \sum\limits_{j=i+1}^{m}r_{j}S_j \\ & \leqslant r_{i+1}\sum\limits_{j=i+1}^{m}S_j\\ & = r_{i+1}\times res_i \end{aligned}\]

\(\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]魔兽世界

另开了,更加SB的题目

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

完成最后一道题目[ZJOI2006]杀蚂蚁

image

posted @ 2022-10-09 19:52  冬天丶的雨  阅读(51)  评论(2编辑  收藏  举报
Live2D