zoukankan      html  css  js  c++  java
  • noip2008

    火柴棍等式

    不知道为什么错了的搜索。。。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int a[]={6,2,5,5,4,5,6,3,7,6};
    int ans,n,e[2002];
    
    void dfs(int sum,int x,int val,int bef,int he,int op,int sit)
    {
       //cout<<sum<<" "<<x<<" "<<val<<" "<<he<<" "<<op<<endl;
       for(int i=0;i<10;i++)
       	if(a[i]<=sum-x) dfs(sum,x+a[i],val*10+i,bef,he,op,sit);
       if(x-sum==0)  
       {
       	if(op==1) 
       		for(int i=sum+2;i<=n-2;i++) dfs(i,x,0,bef,val,2,sit);
       	if(op==2) {if(bef==val) dfs(n,x,0,bef,he+val,3,1); else dfs(n,x,0,bef,he+val,3,0);}
       	if(op==3) 
       		if(he==val) 
       		{
       			if(sit==1) e[bef]=1;
       			else ans++;
       		}
       }
    }		
       					
    int main()
    {
       scanf("%d",&n); n-=4;
       	
       for(int i=2;i<=n-4;i++) dfs(i,0,0,0,0,1,0);
       for(int i=0;i<=2001;i++) if(e[i]) ans++;
       cout<<ans<<endl;
       return 0;
    }
    

    正解(很巧妙,没想到,copy自洛谷第一篇题解)

    #include<stdio.h>
    int main()
    {
            int a[2001]={6},b,c[10]={6,2,5,5,4,5,6,3,7,6},s=0,i,j;
            scanf("%d",&b);
            for(i=1;i<=2000;i++)
            {
                    j=i;
                    while(j>=1)//求每个数所用的火柴棒
                    {
                            a[i]=a[i]+c[j%10];
                            j=j/10;
                    }
            }
            for(i=0;i<=1000;i++)
            {
                    for(j=0;j<=1000;j++)
                    if(a[i]+a[j]+a[i+j]+4==b)s++;//还有加号与等号
            }
            printf("%d",s);
            return 0;
    }
    

    双栈排序

    好难,想不到;
    先考虑一个栈,题解里都只是给出了一个结论:对于i<j<k,存在a[k]<a[i]<a[j],则i,j不能放进一个栈里(题解只证了必要性,我觉得要证充分性才行,但我不会)

    然后就是二分图的标准建模了,把所有的i,j不能放进栈里的连一条边,然后染色,为1的放进第一个栈,为2的放进第二个栈,如果不是二分图就是无解;

    code

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010,inf=0x3f3f3f3f;
    
    int read()
    {
    	int x=0,p=1; char ch=getchar();
    	while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    	if(ch=='-') p=-1,ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    	return x*p;
    }
    
    queue<int> Q;
    int a[N],f[N],stk1[N],stk2[N],e[N][N],col[N];
    int n,top1,top2,now=1;
    
    void bfs(int t)
    {
    	while(Q.size()) Q.pop();
    	Q.push(t); col[t]=1;
    	while(Q.size())
    	{
    		int x=Q.front(); Q.pop();
    		for(int i=1;i<=n;i++)
    			if(e[x][i])
    			{
    				if(col[i]==col[x]) { puts("0"); exit(0);}
    				if(!col[i]) { col[i]=3-col[x]; Q.push(i); }
    			}
    	}
    }
    	
    void print1(int x)
    {
    	while(top1 && a[x]>stk1[top1]) { printf("b "); top1--; }
    	stk1[++top1]=a[x];
    	printf("a ");
    }
    
    void print2(int x)
    {
    	while(top2 && a[x]>stk2[top1]) { printf("d "); top2--; }
    	stk2[++top2]=a[x];
    	printf("c ");
    }
    
    int main()
    {
    	n=read();
    	f[n+1]=inf;
    	for(int i=1;i<=n;i++) a[i]=read();
    	for(int i=n;i>=1;i--) f[i]=min(a[i],f[i+1]);
    	
    	for(int i=1;i<=n;i++)
    		for(int j=i+1;j<=n;j++)
    			if(a[i]<a[j] && f[j+1]<a[i]) e[i][j]=e[j][i]=1;
    	
    	for(int i=1;i<=n;i++) if(!col[i]) bfs(i);
    	
    	for(int i=1;i<=n;i++)
    	{
            if(col[i]==1)
    		{    
                stk1[++top1]=a[i];
                printf("a ");            
            }
            else {
                stk2[++top2]=a[i];
                printf("c ");               
            }
            while((top1 && stk1[top1]==now) || (top2 && stk2[top2]==now))
    		{  
                if(top1 && stk1[top1]==now)
    			{
                    top1--;
                    now++;
                    printf("b ");
                }
                else
    			{
                    top2--;
                    now++;
                    printf("d ");                
                }
            }
    	}
    	return 0;
    }
    

    后面模拟我本来是这样写的,但错了

    void print1(int x)
    {
    	while(top1 && a[x]>stk1[top1]) { printf("b "); top1--; }
    	stk1[++top1]=a[x];
    	printf("a ");
    }
    
    void print2(int x)
    {
    	while(top2 && a[x]>stk2[top1]) { printf("d "); top2--; }
    	stk2[++top2]=a[x];
    	printf("c ");
    }
    
    for(int i=1;i<=n;i++)
    		if(col[i]==1) print1(i);
    		else print2(i);
    	while(top1) { printf("b "); top1--; }
    	while(top2) { printf("d "); top2--; }
    

  • 相关阅读:
    01 《i》控制字体大小 v-for循环绑定类名 v-bind 结合三目运算 动态添加类
    右侧是长方形和半圆结合 光标放上去在规定时间内完成动画
    04-align-content 它对于当单行是没有效果的
    03-flex-wrap是否换行
    02-align-items的用法
    01--顶部的通告特效---仅显示一条一条滚动
    洛谷P2392 kkksc03考前临时抱佛脚(01背包/搜索)
    蓝桥杯 9大臣的旅费(树的直径)
    蓝桥杯 8买不到的数目(数论/线性DP)
    蓝桥杯 7连号区间数(暴力or并查集(?)
  • 原文地址:https://www.cnblogs.com/lzqlalala/p/11379381.html
Copyright © 2011-2022 走看看