博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟,搜索,暴力练习
阅读量:4556 次
发布时间:2019-06-08

本文共 35348 字,大约阅读时间需要 117 分钟。

10.21——————————————————————————————————————————————————————————————————————————-———

1.

/*枚举一个判断一个。 注意油滴半径不能为负数 */#include
#include
#include
#include
#define pi 3.1415926535897932384using namespace std;int x[7],y[7],bx,by,sx,sy;int n;bool vis[7];double r[7],ans;double dis(int i,int j){ double xx1=x[i],xx2=x[j]; double yy1=y[i],yy2=y[j]; return sqrt((xx1-xx2)*(xx1-xx2)+(yy1-yy2)*(yy1-yy2));}double count(int i){ return pi*r[i]*r[i];}void dfs(int cnt,double sum){ if(cnt==n) { ans=max(ans,sum); return; } for(int i=1; i<=n; i++) { if(!vis[i]) { vis[i]=1; r[i]=min(min(abs(x[i]-sx),abs(y[i]-sy)),min(abs(x[i]-bx),abs(y[i]-by))); for(int j=1; j<=n; j++) { if(i==j)continue; if(vis[j])r[i]=max(0.0,min(r[i],dis(i,j)-r[j])); } dfs(cnt+1,sum+count(i)); vis[i]=0; r[i]=0; } }}int main(){ scanf("%d",&n); int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); sx=min(a,c);sy=min(b,d); bx=max(a,c);by=max(b,d); for(int i=1; i<=n; i++)scanf("%d%d",&x[i],&y[i]); dfs(0,0); ans=(bx-sx)*(by-sy)-ans; printf("%.0lf",ans);}
AC

 2.

#include
#define N 101using namespace std;int n,m,ans,cnt;bool vis[N];struct node{ int s,t,len;}word[N];void dfs(int tot,int Last,int rest){ if(rest+tot<=ans) return; ans=max(ans,tot); for(int i=1;i<=n;i++) { if(vis[i] || (word[i].s!=word[Last].t&&Last)) continue; vis[i]=1;rest-=word[i].len; dfs(tot+word[i].len,i,rest); vis[i]=0;rest+=word[i].len; }}int main(){ static char s[N];int len; scanf("%d",&n);int sum=0; for(int i=1;i<=n;i++) { scanf("%s",s+1); len=strlen(s+1); word[i].s=s[1]; word[i].t=s[len]; word[i].len=len;sum+=word[i].len; } dfs(0,0,sum); printf("%d\n",ans); return 0;}
70分暴搜

 3.

#include
#define N 21#define inf 0x3f3f3f3fusing namespace std;int n,m,ans,cnt,mn;int dis[N][N],vis[N];inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}void dfs(int now,int tot,int sum){ if(sum>=ans)return; if(sum+(n-tot+1)*mn>=ans) return; for(int i=1;i<=n;i++) { if(tot==n && i==1) { ans=min(ans,sum+dis[now][i]); return; } if(i==now) continue; if(vis[i]) continue; vis[i]=1; dfs(i,tot+1,sum+dis[now][i]); vis[i]=0; }}int main(){ n=read();mn=inf; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { dis[i][j]=read(); if(i!=j) mn=min(mn,dis[i][j]); } ans=inf;vis[1]=1;dfs(1,1,0); printf("%d\n",ans); return 0;}
90暴搜剪枝

10.22————————————————————————————————————————————————————————————————————————————————

 4.

/*  一个房间可以走多次!可以另外写了一个bfs*/#include
#define N 110using namespace std;int n,m,e[4][2]= {
{
0,1},{
0,-1},{-1,0},{
1,0}};int vis[N][N],bri[N][N],hav[N][N],v[N][N];struct node{ int x,y;} cur,nxt,Map[N][N][10000];node make_node(int x,int y){ node res;res.x=x;res.y=y; return res;}queue
q;void BFS(){ queue
que; while(!que.empty())que.pop(); memset(v,0,sizeof(v)); que.push(make_node(1,1)); v[1][1]=1; while(!que.empty()) { cur=que.front(); que.pop(); for(int i=0; i<4; i++) { int xx=e[i][0]+cur.x,yy=e[i][1]+cur.y; if(xx>n||xx<1||yy>n||yy<1)continue; if(!v[xx][yy]&&bri[xx][yy]) { v[xx][yy]=1; que.push(make_node(xx,yy)); if(!vis[xx][yy]) q.push(make_node(xx,yy)),vis[xx][yy]=1; } } }}void bfs(){ cur=make_node(1,1); vis[1][1]=1;bri[1][1]=1; q.push(cur); while(!q.empty()) { while(!q.empty()) { cur=q.front(); q.pop(); if(hav[cur.x][cur.y]) { for(int i=1; i<=Map[cur.x][cur.y][0].x; i++) { int tx=Map[cur.x][cur.y][i].x,ty=Map[cur.x][cur.y][i].y; if(bri[tx][ty])continue; bri[tx][ty]=1; } } for(int i=0; i<4; i++) { int xx=cur.x+e[i][0],yy=cur.y+e[i][1]; if(xx<1||xx>n||yy<1||yy>n)continue; if(vis[xx][yy]||bri[xx][yy]==0)continue; q.push(make_node(xx,yy)); vis[xx][yy]=1; } } BFS(); }}int main(){ scanf("%d%d",&n,&m); int a,b,c,d; for(int i=1; i<=m; i++) { scanf("%d%d%d%d",&a,&b,&c,&d); Map[a][b][++Map[a][b][0].x].x=c; Map[a][b][Map[a][b][0].x].y=d; hav[a][b]=1; } bfs(); int cnt=0; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(bri[i][j])cnt++; printf("%d",cnt);}
myl太强啦

 5.

#include
#define N 61#define M 1007#define inf 0x3f3f3f3fusing namespace std;char ch[11];int n,m,ans,cnt,xx,yy,step;int dis[N][N][N][N],vis[M][M];int e[8][2]={
{
1,2},{
2,1},{-1,2},{
2,-1},{
1,-2},{-2,1},{-2,-1},{-1,-2}};struct node{ int x,y;}k,u,q[M]; queue
que;inline node make_node(int x,int y){ node res;res.x=x;res.y=y; return res;}inline int abs(int a){ return a<0?-a:a;}inline bool judge(int x,int y){ return (x>0&&x<=n&&y>0&&y<=m);}void bfs(int x,int y){ memset(vis,0,sizeof vis); vis[x][y]=1;step=dis[x][y][x][y]=0; que.push(make_node(x,y)); while(!que.empty()) { u=que.front();que.pop(); step=dis[x][y][u.x][u.y]; for(int i=0;i<8;i++) { xx=u.x+e[i][0];yy=u.y+e[i][1]; if(judge(xx,yy) && !vis[xx][yy]) { vis[xx][yy]=1;dis[x][y][xx][yy]=step+1; que.push(make_node(xx,yy)); } } }}void calculate_distance(){ for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int a=1;a<=n;a++) for(int b=1;b<=m;b++) dis[i][j][a][b]=inf; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) bfs(i,j);}void calculate_step(){ int flag,res=0,tmp=0;ans=inf; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { flag=1;res=0; for(int a=1;a<=cnt;a++) if(dis[q[a].x][q[a].y][i][j]!=inf) res+=dis[q[a].x][q[a].y][i][j]; else{flag=0;break;} if(!flag) continue; ans=min(ans,res+abs(k.x-i)+abs(k.y-j)); for(int a=1;a<=cnt;a++) { tmp=res-dis[q[a].x][q[a].y][i][j]; if(tmp>=ans) continue; for(int r=k.x-2;r<=k.x+2;r++) for(int c=k.y-2;c<=k.y+2;c++) { if(judge(r,c)) ans=min(ans,tmp+dis[r][c][i][j]+dis[r][c][q[a].x][q[a].y]+abs(k.x-r)+abs(k.y-c)); } } }}int main(){ freopen("ly.in","r",stdin); scanf("%d%d",&n,&m); scanf("%s%d",ch,&k.x);k.y=ch[0]-'A'+1; while(~scanf("%s%d",&ch,&q[++cnt].x)) q[cnt].y=ch[0]-'A'+1; calculate_distance(); calculate_step(); printf("%d\n",ans); return 0;}
昨天T今天A?!

#include
#define N 31 #define mod 2333333using namespace std;int n,m,ans,cnt;int rule[N][N],num[N],vis[3000000];char s[N];string s1;void dfs(){ int T=1; for(int i=1;i<=n;i++) T=T*33+num[i],T%=mod; if(vis[T]) return; vis[T]=1; ans++; for(int i=1;i<=n;i++) { for(int j=0;j<=9;j++) { if(!rule[num[i]][j]) continue; int tmp=num[i];num[i]=j; dfs();num[i]=tmp; } }}int main(){// freopen("ly.in","r",stdin); int x,y; scanf("%s%d",s+1,&m);n=strlen(s+1); for(int i=1;i<=n;i++) num[i]=s[i]-'0'; for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); rule[x][y]=1; } ans=0;dfs(); printf("%d\n",ans); return 0;}
40暴搜哈希

#include
#define N 51using namespace std;int n,m,ans,cnt,res;int head[N],vis[N];struct edge{ int u,v,w,nxt;}e[N<<1];inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}inline void add(int u,int v,int w){ e[++cnt].v=v;e[cnt].nxt=head[u];e[cnt].w=w;head[u]=cnt;}void dfs(int u,int sum){ ans=max(ans,sum); for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(vis[v]) continue; vis[v]=1;dfs(v,sum+e[i].w); vis[v]=0; }return;}int main(){ int x,y,z; n=read();m=read(); for(int i=1;i<=m;i++) { x=read();y=read();z=read(); add(x,y,z);add(y,x,z); } for(int i=1;i<=n;i++) { memset(vis,0,sizeof vis); vis[i]=1;dfs(i,0); } printf("%d\n",ans); return 0;}
回溯..

 CF196B

/*如果一个图能从起点到达无穷远,一定能从图的任意一点到达下一张图与原图对应的点如何判断这个点是否能再次到达是关键可以记录取模的横纵坐标x, y,记录没有取模的坐标lx,ly开始遍历这个迷宫x,y一定分别等于lx,ly 继续无限遍历下去如果一个点被访问过了但它的x,y不等于lx,ly则一定被再次走过。 */#include
#define N 1501using namespace std;int n,m,ans,cnt,sx,sy,flag;int vis[N][N][3],a[N][N];int dx[4]={
1,-1,0,0};int dy[4]={
0,0,1,-1};void dfs(int x,int y,int lx,int ly){ if(flag) return; if((vis[x][y][1]!=lx || vis[x][y][2]!=y) && vis[x][y][0]) { flag=1;return; } vis[x][y][1]=lx;vis[x][y][2]=ly;vis[x][y][0]=1; for(int i=0;i<4;i++) { int xx=(x+dx[i]+n)%n,yy=(y+dy[i]+m)%m; int lxx=lx+dx[i],lyy=ly+dy[i]; if(a[xx][yy]) continue; if(!vis[xx][yy][0] || vis[xx][yy][1]!=lxx || vis[xx][yy][2]!=lyy) dfs(xx,yy,lxx,lyy); }}int main(){ char ch; while(scanf("%d%d",&n,&m)!=EOF) { flag=0; memset(vis,0,sizeof vis); memset(a,0,sizeof a); for(int i=0;i
>ch; if(ch=='#') a[i][j]=1; else if(ch=='S') sx=i,sy=j; } dfs(sx,sy,sx,sy); if(flag) printf("Yes\n"); else printf("No\n"); } return 0;}
好题

 10.23————————————————————————————————————————————————————————————————————————————————

9. ()

/*二分答案暴搜+剪枝 */#include
#define N 1011#define inf 0x3f3f3f3fusing namespace std;int n,m,ans,cnt,tmp,tot,waste,mid;int len[N],a[N],vis[N];int sum[N],cur[N];inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}inline int cmp(int a,int b){
return a>b;}bool dfs(int lim,int now){ if(!lim) return true; if(tot-waste
=a[lim]) { len[i]-=a[lim]; if(len[i]
>1; if(dfs(mid,1)) ans=mid,l=mid+1; else r=mid-1; } printf("%d\n",ans); return 0;}
这个搜索比较迷..

/*O(n) dfs预处理 */#include
#define N 1000007#define ll long longusing namespace std;ll n,m,ans,cnt;ll head[N],son[N],deep[N];struct edge{ ll u,v,nxt,w;}e[N<<1];inline ll read(){ ll x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}inline void add(ll u,ll v,ll w){ e[++cnt].v=v;e[cnt].nxt=head[u];e[cnt].w=w;head[u]=cnt;}inline int abs(int a){
return a<0?-a:a;}void dfs(int u,int from,int c){ son[u]=1;deep[u]=c; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(v==from) continue; dfs(v,u,c+1);son[u]+=son[v]; }}void Dfs(int u,int from){ for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(v==from) continue; if(deep[v]>deep[u]) ans+=abs(n-son[v]*2)*e[i].w; else ans+=abs(n-son[u]*2)*e[i].w; Dfs(v,u); }}int main(){ freopen("ly.in","r",stdin); ll x,y,z; n=read(); for(int i=1;i
NOI2011......

10.25————————————————————————————————————————————————————————————————————————————————

/*模拟题要在写之前构思好代码的简洁性很重要!!所以一定要想更好的办法把代码写简单。 */#include 
#define mod 1000000007#define N 101using namespace std;int n,m,t,flag;int f[N][N],vis[N][N];char a[N][N];void dfs(int x,int y){ if(y>m)x++,y=1; if(x>n) return; if(a[x][y]!=' ') { if(a[x][y]==a[x+1][y] && a[x][y]==a[x+2][y]) { vis[x][y]=vis[x+1][y]=vis[x+2][y]=1; flag=1; } if(a[x][y]==a[x][y+1] && a[x][y]==a[x][y+2]) { vis[x][y]=vis[x][y+1]=vis[x][y+2]=1; flag=1; } if(a[x][y]==a[x+1][y+1] && a[x][y]==a[x+2][y+2]) { vis[x][y]=vis[x+1][y+1]=vis[x+2][y+2]=1; flag=1; } if(a[x][y]==a[x+1][y-1] && a[x][y]==a[x+2][y-2]) { vis[x][y]=vis[x+1][y-1]=vis[x+2][y-2]=1; flag=1; } } dfs(x,y+1);}int main(){ cin>>n>>m; for(int i=1; i<=n; i++) cin>>a[i]+1; while(1) { flag=0; memset(vis,0,sizeof(vis)); dfs(1,1); if(flag==0) break; for(int j=1; j<=m; j++) { int k=n; for(int i=n; i>=1; i--) { char p=a[i][j]; a[i][j]=' '; if(vis[i][j]==0)a[k--][j]=p; } } } for(int i=1; i<=n; i++) cout<
<
唉,人生啊

#include
#define N 107#define inf 0x3f3f3f3fusing namespace std;int g[N][N],a[N][N];int n,m,sum;bool check(int r,int c)//判断r*c是否可行{ if((sum%(r*c)))return false;//可行性剪枝 else { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=g[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]) { int t=a[i][j]; for(int q=1;q<=r;q++) for(int w=1;w<=c;w++) { if(i+q-1>n||j+w-1>m)return false; a[i+q-1][j+w-1]-=t; if(a[i+q-1][j+w-1]<0) return false; } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j])return false; return true; }}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&g[i][j]),sum+=g[i][j]; int ans=inf; for(int r=1;r<=n;r++) for(int c=1;c<=m;c++) if(check(r,c)) ans=min(ans,(sum)/(r*c)); cout<
<
暴搜+剪枝
/*我好蠢啊 20暴力*/#include
#define inf 0x3f3f3f3f#define N 1001using namespace std;int n,m,ans,cnt,opt;int num[N][N],tmp[N][N];inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}bool judge(){ for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(num[i][j]!=0) return false; return true;}void dfs(int x,int y,int r,int c){ if(opt) return; if(cnt>=ans) {opt=1;return;} if(judge()){ans=min(ans,cnt);opt=1;return;} if(y==m+1 ||y+c-1>m) y=1,x++; if(x+r-1>n)return; int flag=0; for(int i=x;i
我是智障

10.28——————————————————————————————————————————————————————————————————————————————

#include
#define N 1001using namespace std;int n,m,ans,cnt;struct node{ int s,t; bool operator < (const node &a) const{ return t
'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}int main(){ n=read();ans=0x3f3f3f3f; for(int i=1;i<=n;i++) p[i].s=read(),p[i].t=read(); sort(p+1,p+n+1);int now=0,flag=0; for(int i=1;i<=n;i++) { if(now+p[i].s>p[i].t) {flag=1;break;} now+=p[i].s;ans=min(ans,p[i].t-now); } if(flag){printf("-1\n");return 0;} else printf("%d\n",ans); return 0;}
1A

10.30————————————————————————————————————————————————————————————————————————————————

    

#include
#define N 40#define mod 2333333#define M 500using namespace std;int n,m,ans,cnt,opt,s;int head[M<<1],vis[N],V[2333337],light[N];struct edge{ int u,v,nxt;}e[M<<1];inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}inline void add(int u,int v){ e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;}bool judge(int u){ for(int i=1;i<=n;i++) if(!light[i]) return false; return true;}int get(){ int ss=1; for(int i=1;i<=n;i++) { ss+=ss*33+(light[i]+1)%mod; ss%=mod; } return ss;}void dfs(int u,int tot){ if(ans<=tot) return; if(judge(1)) { ans=min(ans,tot); return; } for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(vis[v]) continue;vis[v]=1; dfs(v,tot); vis[v]=0;light[v]^=1; for(int j=head[v];j;j=e[j].nxt) light[e[j].v]^=1; s=get(); if(V[s]) continue;V[s]=1; dfs(v,tot+1); }}int main(){ int x,y; n=read();m=read(); for(int i=1;i<=m;i++) { x=read();y=read(); add(x,y);add(y,x); }ans=0x3f3f3f3f; for(int i=head[1];i;i=e[i].nxt) light[e[i].v]^=1; vis[1]=1;light[1]^=1;dfs(1,1); memset(vis,0,sizeof vis); memset(light,0,sizeof light); memset(V,0,sizeof V); vis[1]=1; dfs(1,0); printf("%d\n",ans); return 0;}
10分蜜汁wa
/*折半搜索经典题注意每个点随时都可以去。搜一半,map记录这一半所有状态的最小步数。搜另一半时,用当前状态步数+记录好的当前补集步数即可。 */#include
#define inf 1000000000#define N 40#define ll long longusing namespace std;int n,m,cnt,ans=inf;int a[N];bool flag;ll ed,p[N],bin[N];map
step;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}void dfs(int x,ll sta,int tot)//sta是当前状态,ed是末状态 { if(x==cnt+1) { if(sta==ed)ans=min(tot,ans); if(!flag) { int t=step[sta]; if(!t || t>tot)step[sta]=tot; } else { int t=step[ed-sta];//取记录好的当前状态的补集 if(!t)return; ans=min(t+tot,ans); } return; } dfs(x+1,sta,tot); dfs(x+1,sta^p[x],tot+1);}int main(){ bin[1]=1;for(int i=2;i<40;i++)bin[i]=bin[i-1]<<1; n=read();m=read(); ed=bin[n+1]-1; for(int i=1;i<=m;i++) { int a=read(),b=read(); p[a]|=bin[b];p[b]|=bin[a];//记录每个点能改变那些点的状态 } for(int i=1;i<=n;i++)p[i]+=bin[i];//也能改变当前点的状态 cnt=n/2;dfs(1,0,0); flag=1; cnt=n;dfs(n/2+1,0,0); printf("%d\n",ans); return 0;}
折半搜索

#include
#define N 100007using namespace std;int n,m,ans,cnt,num,tot;int head[N],Head[N],dfn[N],low[N],scc[N],bel[N];int V[N],A[N];bool in_st[N],vis[N];stack
st;struct edge{ int u,v,nxt;}e[N<<1],E[N<<1];inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}inline void add(int u,int v){ e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;}inline void add_(int u,int v){ E[++cnt].v=v;E[cnt].nxt=Head[u];Head[u]=cnt;}void Tarjan(int u){ dfn[u]=low[u]=++cnt; st.push(u);in_st[u]=1; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].v; if(!dfn[v]) Tarjan(v),low[u]=min(low[u],low[v]); else if(in_st[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { num++;tot=0; while(st.top()!=u) { tot++; bel[st.top()]=num; in_st[st.top()]=0;st.pop(); } tot++; bel[st.top()]=num;scc[num]=tot; in_st[st.top()]=0;st.pop(); }}void dfs(int u,int sum){ if(V[u]) {ans+=A[u];return;} ans=sum; for(int i=Head[u];i;i=E[i].nxt) { int v=E[i].v; if(vis[v]) continue; vis[v]=1;dfs(v,sum+scc[v]); }}int main(){ int x; n=read(); for(int i=1;i<=n;i++) { x=read();add(i,x); } cnt=0; for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i); cnt=0; for(int i=1;i<=n;i++) for(int j=head[i];j;j=e[j].nxt) if(bel[i]!=bel[e[j].v]) add_(bel[i],bel[e[j].v]); for(int i=1;i<=n;i++) { ans=0;memset(vis,0,sizeof vis); if(!V[bel[i]]) { vis[bel[i]]=1,dfs(bel[i],scc[bel[i]]),A[bel[i]]=ans,V[bel[i]]=1; } else ans=A[bel[i]]; printf("%d\n",ans); } return 0;}
记忆化搜索

10.31————————————————————————————————————————————————————————————————————————————————

16.

/*预处理每个点能往上下左右扩展的距离n^2枚举每个点n^2暴力扩展复杂度n^4emmm 加点优化就过了 */#include
#define N 201using namespace std;int n,m,ans,cnt;int a[N][N];int ex_up[N][N],ex_down[N][N],ex_L[N][N],ex_R[N][N];char ch;int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>ch; a[i][j]=(ch=='.'?0:1); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cnt=0; while(j+cnt<=m && !a[i][j+cnt]) cnt++; if(cnt) ex_R[i][j]=cnt-1; cnt=0; while(j-cnt>=1 && !a[i][j-cnt]) cnt++; if(cnt) ex_L[i][j]=cnt-1; cnt=0; while(i-cnt>=1 && !a[i-cnt][j]) cnt++; if(cnt) ex_up[i][j]=cnt-1; cnt=0; while(i+cnt<=n && !a[i+cnt][j]) cnt++; if(cnt) ex_down[i][j]=cnt-1; } ans=1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(!ex_R[i][j]) continue; if((ex_R[i][j]+1)*(ex_down[i][j]+1)<=ans) continue; for(int x=j;x<=j+ex_R[i][j];x++) { if(!ex_down[i][x]) continue; for(int y=i;y<=i+ex_down[i][j];y++) { if(i+ex_down[i][x]>n || j+ex_R[y][j]>m) continue; if(i+ex_down[i][x]>=y && j+ex_R[y][j]>=x) ans=max(ans,(x-j+1)*(y-i+1)); } } } printf("%d\n",ans); return 0;}
暴力枚举+优化

11.1——————————————————————————————————————————————————————————————————————————————————

17.

#include
#define N 30 #define M 3111111 #define mod 2333333 using namespace std; int n,m,ans,cnt,flag; int a[N],vis[N],V[M]; int cur[N],sum[N]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(x=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } /*bool dfs2(int cur[],int k,int val,int n) { if(n==2 && cur[1]!=cur[2]) return false; if(flag) return true; if(val==sum[n]-val) {flag=1;return true;} if(k==n && !flag) return false; for(int i=k+1;i<=n;i++) dfs2(cur,i,val+cur[i],n),dfs2(cur,i,val,n); if(!flag)return false; }*/ bool judge() { int cnt_=0,S=1; static int dp[N][M]; memset(dp,0,sizeof dp); memset(cur,0,sizeof cur); memset(sum,0,sizeof sum); for(int i=1;i<=n;i++) if(vis[i]) cur[++cnt_]=a[i],sum[cnt_]=sum[cnt_-1]+cur[cnt_]; sort(cur+1,cur+cnt_+1); for(int i=1;i<=cnt_;i++) S+=S*33+cur[i],S%=mod; if(V[S]) return false;V[S]=1;flag=0; if(sum[cnt_]%2) return false; if(cnt_==2 && cur[1]!=cur[2]) return false; for(int i=0;i<=cnt_;i++) dp[i][cur[i]]=dp[i][0]=1; for(int i=1;i<=cnt_;i++) for(int j=1;j<=sum[cnt_];j++) { if(j>=cur[i-1]) dp[i][j]=(dp[i-1][j] || dp[i-1][j-cur[i]]); else dp[i][j]=dp[i-1][j]; } return (dp[cnt_][sum[cnt_]/2]); } void dfs(int lim,int k,int tot) { if(tot==lim) { if(judge()) ans++; return; } if(k>n) return; for(int i=k+1;i<=n;i++) { if(vis[i]) continue; vis[i]=1;dfs(lim,k+1,tot+1); vis[i]=0; } } int main() { freopen("ly.in","r",stdin); n=read(); for(int i=1;i<=n;i++) a[i]=read(); cnt=2; while(cnt<=n) { memset(vis,0,sizeof vis); dfs(cnt,0,0); cnt++; } printf("%d\n",ans); return 0; }
24暴搜
/*折半搜索枚举每个数如何选择,放入A就加,放入B就减 状压判断每个数的具体选择状态最后双指针扫统计答案  若集合A的和 + 集合B的和为0那么就说明这两个集合构成的答案合法 */#include
#define N 22#define ll long longusing namespace std;int n,v[N<<1],maxdep,cnta,cntb;bool vis[1<
b.x;}inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(x=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; }void dfs(int dep,int sum,int now,int flag){ if(dep==maxdep+1) { if(!flag) a[++cnta].x=sum,a[cnta].state=now; else b[++cntb].x=sum,b[cntb].state=now; return; } dfs(dep+1,sum,now,flag); dfs(dep+1,sum+v[dep],now | (1<<(dep-1)),flag); dfs(dep+1,sum-v[dep],now | (1<<(dep-1)),flag);}int main(){ n=read(); for(int i=1; i<=n; i++)v[i]=read(); maxdep=n/2;dfs(1,0,0,0); maxdep=n; dfs(n/2+1,0,0,1); sort(a+1,a+1+cnta,cmp1); sort(b+1,b+1+cntb,cmp2); int l=1,r=1; while(l<=cnta&&r<=cntb) { while(-a[l].x
<=cntb)r++; int pos=r; while(r<=cntb&&-a[l].x==b[r].x) { if(!vis[a[l].state | b[r].state]) { vis[a[l].state | b[r].state]=1; ans++; }r++; } if(l
折半搜索

18.

#include
#define N 45#define M 1000007#define ll long longusing namespace std;ll n,m,ans,cnt,mx,flag;ll val[N],f[N][M];inline ll read() { ll x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(x=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; }void dfs(int k,ll sum){ if(sum>m) return; if(k==n) { ans++;return; } dfs(k+1,sum); dfs(k+1,sum+val[k+1]);}void dp(){ f[0][m]=1; for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) { f[i][j]+=f[i-1][j]+f[i-1][j+val[i]]; } for(int i=0;i<=m;i++) ans+=f[n][i];}int main(){ //freopen("ly.in","r",stdin); n=read();m=read(); for(int i=1;i<=n;i++) val[i]=read(); if(m<=1e6) dp(); else dfs(0,0); printf("%lld\n",ans); return 0;}
80 dfs+dp
/*折半搜索 */#include
#define ll long long#define N 55using namespace std;ll n,m,mid,cnta,cntb,ans;ll w[N],suma[1<<21],sumb[1<<21];inline ll read() { ll x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(x=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; }inline void dfs(int l,int r,ll sum,ll a[],ll &cnt){ if(sum>m)return; if(l>r) { a[++cnt]=sum;return; } dfs(l+1,r,sum+w[l],a,cnt); dfs(l+1,r,sum,a,cnt);}int main(){ n=read();m=read(); for(int i=1;i<=n;i++)w[i]=read();; mid=n/2; dfs(1,mid,0,suma,cnta); dfs(mid+1,n,0,sumb,cntb); sort(suma+1,suma+1+cnta); for(int i=1; i<=cntb; i++) ans+=upper_bound(suma+1,suma+1+cnta,m-sumb[i])-suma-1; printf("%lld\n",ans); return 0;}
折半搜索

#include
#define N 20using namespace std;int n,m,ans,cnt;int a[N],vis[N],dis[N][N],fri[N][4];inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(x=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; }inline int abs_(int a){
return a<0?-a:a;}void calc(){ static int pos[N]; for(int i=1;i<=n;i++) pos[a[i]]=i; int tot=0;memset(dis,0,sizeof dis); for(int i=1;i<=n;i++) for(int j=1;j<=3;j++) { if(dis[i][fri[i][j]] || dis[fri[i][j]][i]) continue; dis[i][fri[i][j]]=dis[fri[i][j]][i]=1;tot+=abs_(pos[i]-pos[fri[i][j]]); }ans=min(ans,tot);}void dfs(int k){ for(int i=1;i<=n;i++) { if(!vis[i]) { vis[i]=1;a[k]=i; if(k==n) calc(); dfs(k+1); vis[i]=0; } }}int main(){ //freopen("ly.in","r",stdin); n=read(); for(int i=1;i<=n;i++) for(int j=1;j<=3;j++) fri[i][j]=read(); ans=0x3f3f3f3f;dfs(1); printf("%d\n",ans); return 0;}
49暴搜
/*nowtot:当前总距离; links:已经访问的所有奶牛中,有多少路线没有找到,(即某奶牛的朋友还没有找到); remain:已经访问的所有奶牛中,没有找到的路线的长度总和,(是当前,并不是所有);因为每条路线至少是1,所以我们假定所有没找到的路线开始都为1;每次,remain+links,即当前位置,还没有找到的所有路线都+1(显然); 因此remain是我们的方案的下限,即最小的估值(不可能更小了);其实,这只是个“随机”值,但这个随机值不会让答案错误; */#include
#define N 20using namespace std;int fr[N][5],a[N],pos[N];int n,ans,cnt;bool vis[N];void dfs(int x,int nowtot,int links,int remain){ if(x==n+1) ans=min(ans,nowtot); if(remain+nowtot >= ans) return;//最优化剪枝 for(int i=1;i<=n;i++) { if(!pos[i]) { int new_link=3,sum=0;//每个奶牛开始有三个朋友; pos[i]=x;//第i个奶牛放在x上; for(int j=1;j<=3;j++) { if(pos[fr[i][j]]!=0) { sum+=abs(x-pos[fr[i][j]]);//发现这条路线已经确定; new_link-=2;//friend路线-1,当前奶牛同样-1,总的减2; } } dfs(x+1,nowtot+sum,links+new_link,remain+(links+new_link)-sum); pos[i]=0; } } return;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)for(int j=1;j<=3;j++) scanf("%d",&fr[i][j]); ans=0x3f3f3f3f; dfs(1,0,0,0); printf("%d\n",ans); return 0;}
A*

/*暴搜2^(n+m)折半搜索 */#include
#define N 27#define ll long longusing namespace std;ll n,m,k,ans,flag;ll a[N][N];map
M[N][N];inline ll read(){ ll x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(x=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}void dfs(int dep,int x,int y,ll sta){ if(x<1 || x>n || y<1 || y>m) return; if(!flag) sta^=a[x][y]; if(x+y==dep) { if(!flag){M[x][y][sta]++;return;} else{ans+=M[x][y][k^sta];return;} } if(!flag){ dfs(dep,x+1,y,sta);dfs(dep,x,y+1,sta); } else{ sta^=a[x][y]; dfs(dep,x-1,y,sta);dfs(dep,x,y-1,sta); }}int main(){ n=read();m=read();k=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read(); flag=0;dfs((n+m+2)/2,1,1,0); flag=1;dfs((n+m+2)/2,n,m,0); printf("%lld\n",ans); return 0;}
折半搜索

 11.2————————————————————————————————————————————————————————————————————————————————

21.

/*折半搜索,把取模后的和存起来 双指针统计答案 */#include
#define N 300000using namespace std;int a[N],p[N],q[N];int k,t,ans,n,m,b,dep,flag;inline int max(int x,int y){
return x>y? x:y;}inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}void dfs(int now,int sum){ if(now==dep) { if(!flag) { p[++k]=sum,p[++k]=(sum+a[b])%m;return; } else { q[++t]=sum,q[++t]=(sum+a[n])%m; return ; } } dfs(now+1,sum); dfs(now+1,(sum+a[now])%m);}int main(){ n=read(),m=read(),b=n>>1;dep=b; for(int i=1; i<=n; ++i) a[i]=read(); if(n==1) printf("%d",a[1]%m),exit(0); flag=0;dfs(1,0); dep=n;flag=1;dfs(b+1,0); int L=0,R=t; sort(p+1,p+k+1);sort(q+1,q+t+1); while(L<=k) { while(p[L]+q[R]>=m) --R; ans=max(ans,p[L]+q[R]),++L; } ans=max(ans,p[k]+q[t]-m); printf("%d",ans); return 0;}
折半搜索

 11.4—————————————————————————————————————————————————————————————————————————————————

22.

/*直接枚举判断显然不可以。 考虑折半搜索。可以把这16个数字拆成2个子集,各自生成所有大小1e18及以下的积。 但也需要使两个乘积组成的集合尽量接近。可以预先造出极限数据试一试集合里能有多少数 对于最坏情况,即如下数据162 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53分为2 3 5 7 11 13 和  17 19 23 29 31 37 41 43 47 53 两个集合时这两个集合生成的1e18及以下的积的数量分别为 958460个 和 505756个,并不大 集合中数必须两两不等。最后统计答案, 两个集合生成的积各自排一下序然后二分答案,对于每个答案 u,可以O(|S|)双指针得到他是第几大。具体做法是枚举从到小枚举第一个集合的积 t1,然后计算一下第二个集合的积中有多少积和 t1 相乘小于等于 u,由于是从大到小枚举的,所以t1必然递增所以第二个集合的积中符合条件的积的数量也必然是递增的,所以只要扫一遍就行。 */#include
#define ll long long#define inf 1e18#define N 24using namespace std; vector
seg[2];int p[N],n;ll ansid; void dfs(int L,int R,ll val,int id){ seg[id].push_back(val); for(int i=L;i<=R;i++) if(inf/p[i]>=val) dfs(i,R,val*p[i],id);} ll cnt(ll num){ int j=0; ll ret=0; for(int i=seg[0].size()-1;i>=0;i--) { while(j
>1; if(cnt(mid)>=ansid) R=mid; else L=mid; } cout<
<
>ansid; solve(); return 0;}
折半搜索

23.

#include
#define inf 1000000000#define ll long longusing namespace std;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int n,m,K;double ave;int a[15][15];int s[15][15];double t[15][15][15][15][15];double dfs(int a,int b,int c,int d,int k){ double &res=t[a][b][c][d][k]; if(res!=-1)return res; if(k==0) { res=s[b][d]+s[a-1][c-1]-s[a-1][d]-s[b][c-1]; res=(res-ave)*(res-ave); return res; } res=1e9; for(int i=a+1;i<=b;i++) for(int j=0;j
记忆化搜索

11.8—————————————————————————————————————————————————————————————————————————————————

#include
#define N 51#define inf 0x3f3f3f3f#define eps 0.00001using namespace std;int n,m,T,ans,cnt[10000000],flag,dfn;double x[N],y[N],a,b;int died[N],vis[N][N];int d[N][N],cur[1000000][51];void calc(int i,int j)//算a,b { flag=0; double x1=x[i],x2=x[j],y1=y[i],y2=y[j]; if(x1==x2) {a=0,b=x1;return;} b=(x2*x2*y1-x1*x1*y2)/(x1*x2*x2-x1*x1*x2); a=(y1-b*x1)/(x1*x1);}void work(double a,double b,int dfn){ cnt[dfn]=0; for(int i=1;i<=n;i++) { if(died[i]) continue; if(a*x[i]*x[i]+b*x[i]+eps>=y[i] && a*x[i]*x[i]+b*x[i]-eps<=y[i]) died[i]=1,cnt[dfn]++,cur[dfn][cnt[dfn]]=i;//cur记录这只鸟打掉的猪 }}void dfs(int use,int rest,int dfn)//用了多少鸟,剩下多少猪 {/* int d_bug=0; for(int i=1;i<=n;i++) if(died[i]) d_bug++; if(n-rest!=d_bug) { cout<
<<" "<
<
=ans) return; if(m==1 && use>n/3+1) return;//剪枝 if(rest==0) { ans=min(ans,use); return; } for(int i=1;i<=n;i++) { if(died[i]) continue; for(int j=i+1;j<=n;j++) { if(died[j]) continue; if(vis[i][j] || vis[j][i] || d[i][j] || d[j][i]) continue; calc(i,j);//算抛物线 if(a>=0){d[i][j]=d[j][i]=1;continue;}//d数组为了剪枝;a<0时,i,j一定不能组成需要的抛物线 work(a,b,dfn);//算这条抛物线能打掉多少 vis[i][j]=vis[j][i]=1;//标记这条抛物线 dfs(use+1,rest-cnt[dfn],dfn+1); for(int k=1;k<=cnt[dfn];k++) died[cur[dfn][k]]=0;//把这条抛物线打掉的复活 vis[i][j]=vis[j][i]=0;//memset(cur,0,sizeof cur); } if(!died[i]) died[i]=1,dfs(use+1,rest-1,dfn+1),died[i]=0;//没有点跟i组成抛物线,单独一条。 }}void clear(){ memset(died,0,sizeof died); memset(d,0,sizeof d); memset(vis,0,sizeof vis);}int main(){ scanf("%d",&T); while(T--) { clear(); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]); ans=inf;dfs(0,n,1); printf("%d\n",ans); } return 0;}
60dfs

 25

/*我才不要写状压dp呢!! 状压dfs对于每一行dfs一次。顺便记录这一行的状态能否对下一行的状态产生贡献。*/#include
#define N 100000#define S 30#define mod 100000000using namespace std;int m,n,ans;int f[S][N],a[S];inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}void dfs(int x,int y,int sta,int nxt)//nxt是下行状态 { if(y>=n) { f[x+1][nxt]+=f[x][sta]; f[x+1][nxt]%=mod; return; } dfs(x,y+1,sta,nxt);//不放 if(!(sta&(1<
状压dfs

 

转载于:https://www.cnblogs.com/L-Memory/p/9822721.html

你可能感兴趣的文章
北京信息科技大学第十一届程序设计竞赛(重现赛)B
查看>>
北京信息科技大学第十一届程序设计竞赛(重现赛)H
查看>>
Codeforces Round #572 (Div. 2) A.
查看>>
POJ - 3984 迷宫问题
查看>>
Codeforces Round #572 (Div. 2)B
查看>>
[kuangbin带你飞]专题一 简单搜索 C
查看>>
HDU - 1372 Knight Moves(bfs入门)
查看>>
牛客假日团队赛5 H
查看>>
A计划 HDU - 2102
查看>>
Codeforces Round #570 (Div. 3 )A
查看>>
牛客假日团队赛6 F. Mud Puddles
查看>>
Codeforces Round #573 (Div. 2).A
查看>>
吉首大学2019年程序设计竞赛(重现赛)H 蛇皮走位
查看>>
HDU 2544 最短路(spfa算法)
查看>>
[kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home(spfa算法)
查看>>
[kuangbin带你飞]专题四 最短路练习 E - Currency Exchange(判断负环)
查看>>
[kuangbin带你飞]专题四 最短路练习 F - Wormholes (判断负环)
查看>>
[kuangbin带你飞]专题四 最短路练习 D - Silver Cow Party(最短路spfa+转置邻接矩阵)...
查看>>
[kuangbin带你飞]专题四 最短路练习G - MPI Maelstrom(链式前向星(邻接表)||邻接矩阵)spfa算法...
查看>>
[kuangbin带你飞]专题四 最短路练习 H - Cow Contest (floyed传递背包)
查看>>