zoukankan      html  css  js  c++  java
  • hdu 4272 LianLianKan

    解题思路:

      1.贪心(错误):无论取就近的数删除还是最远的数删除,均不对;

      相应测试数据:   3 2 4 4 1 3 1 2 1 1

                1 4 4 3 1 3 2 2 1 1

      2.搜索(可以水过数据,必须处理各个数出现偶数次,否则会超时)

        处理1:

        

    map<int>mp;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        mp[a[i]]++;
        ……
    }
    if(n&1)
    {
        printf("0
    ");
        continue;
    }
    //加个map判断就是0ms,否则就是TLE
    map<int,int>::iterator it;
    for(it=mp.begin(); it!=mp.end(); it++)
    {
        if((it->second)%2==1)
        {
            t=0;
            break;
        }
        ……
    }

        处理2:

    while(~scanf("%d",&n))
    {
        int t=0;
        for(i=1; i<=n; i++)    // 改动了起点 将起点定位11  可防止RE
        {
            scanf("%d",&a[i+10]);
            t=t^a[i+10];
        }
        if(t) // a[n]中有数的个数为奇数的话 直接输出0
        {
            printf("0
    ");
            continue ;
        }
         ……      
    }
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define maxn 1015
    using namespace std;
    
    int n,m,ans,flag;
    int a[maxn];
    
    void dfs(int pos)
    {
        //if(flag) return ;
        /*printf("%#d
    ",pos);
        for(int j=n+10; j>10; j--)
            if(a[j]!=-1)printf("%d ",a[j]);
        printf("
    ");*/
        int i,tmp,tp;
        if(pos==10)
        {
            flag=1;// 如果搜到结果就直接return
            return ;
        }
        if(a[pos]==-1)//前一个被找到
        {
            dfs(pos-1);
        }
        else
        {
            int j=pos;
            int p=0;
            for(i=pos-1; j-i<=5; i--)   // 每次只搜5的宽度
            {
                if(a[i]==-1)p++,i++;
                //printf("%d %d
    ",a[j],a[i-p]);
                if(a[i-p]==a[pos])
                {
                    tmp=a[i-p];
                    tp=a[pos];
                    a[i-p]=-1;
                    a[pos]=-1;
                    dfs(pos-1);
                    a[i-p]=tmp;
                    a[pos]=tp;
                }
                if(flag)break;
            }
        }
    }
    int main()
    {
        int i,j,t;
        for(i=0; i<=10; i++)
        {
            a[i]=-1;
        }
        while(~scanf("%d",&n))
        {
            t=0;
            for(i=1; i<=n; i++)    // 改动了起点 将起点定位11  可防止RE
            {
                scanf("%d",&a[i+10]);
                t=t^a[i+10];//||t
            }
            if(t) // 如果n为奇数 或者a[n]中有数的个数为奇数的话 直接输出0
            {
                printf("0
    ");
                continue ;
            }
            flag=0;
            dfs(n+10);
            printf("%d
    ",flag);
        }
        return 0;
    }
    View Code

    对于数据1 2 2 3 3 4 4 1 ,我认为不符合题意输出应为0(提供的代码是此理解)

      3。模拟亦可水过

    1. 12 
    2. 1 2 2 1 3 1 1 1 1 1 1 3 
    3. 第一步消去 1 1得  2 2 3 1 1 1 1 1 1 3 
    4. 第二步消去 2 2得  3 1 1 1 1 1 1 3 
    5. 第三步由于两个3之间差距大于等于6,那么我们先消去1,得 3 1 1 1 1 3 
    6. 第四步 消去3 3得 1 1 1 1  
    7. ...... 
    8. 那么从上面这个例子可以看出,并不是要求必须一个一个的消除过去,而是可以选择的。那么这样就可以知道只要相同的水果个数为偶数那么肯定是可以消去的,否则不行。 (题意不是这样的~~o(>_<)o ~~)
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    using namespace std;
    #define MAXN 1010
    #define INF 0xFFFFFFF
    int n;
    vector<int>v;
    
    void solve()
    {
        int flag, i;
        vector<int>::iterator it1, it2;
        while (1)
        {
            //for(int j=0;j<v.size();j++)
            //printf("%d ",v[j]);
            //printf("
    ");
            flag = 0;
            if (v.size() <= 1) break;/*只有一个元素的肯定不行*/
            it1 = v.begin();
            for (; it1 != v.end(); it1++)
            {
                for (it2 = it1 + 1, i = 1; i < 6 && it2 != v.end(); i++ , it2++)
                {
                    if (*it1 == *it2)
                    {
                        v.erase(it1);/*这里删除了it1后it2会往回移动一个*/
                        v.erase(it2-1);/*所以由上面的可知这里删除it2-1位置*/
                        flag = 1 ;
                        break;
                    }
                }
                if (flag) break;
            }
            if (!flag || !v.size()) break;/*如果flag为0或v为空退出*/
        }
        if (v.size()) printf("0
    ");
        else printf("1
    ");
    }
    
    int main()
    {
        //freopen("input.txt", "r", stdin);
        int tmp;
        while (scanf("%d", &n) != EOF)
        {
            v.clear();
            for (int i = 0; i < n; i++)
            {
                scanf("%d", &tmp);
                v.push_back(tmp);/*全部插入vector*/
            }
            solve();
        }
        return 0;
    
    }
    View Code

      4,那么也可这么水

    #include<stdio.h>
    int main()
    {
        int n,i,t,x;
        while(scanf("%d",&n)!=EOF)
        {
            t=0;
            for(i=0;i<n;i++)
            {
                scanf("%d",&x);
                t=t^x;
            }
            if(t)
                printf("0
    ");
            else
                printf("1
    ");
        }
        return 0;
    }

    无力吐槽啊啊啊啊啊啊啊……

      5,dp(正解)

    本人不善dp,提供搜索代码:

  • 相关阅读:
    序列号问题(入库检带序列号,冲销入库无序列号(变态情况))
    sm30表维护做排序
    HR函数学习03——维护信息类型1008
    HR函数学习02——分配组织单位
    机器学习知识积累
    机器学习数学知识积累之高等数学微积分
    机器学习数学知识积累之线性代数解析几何,微积分
    机器学习数学知识积累之数理统计
    在博客园使用LaTex编辑学术论文级别的data science文章
    机器学习数学知识积累之概率论
  • 原文地址:https://www.cnblogs.com/XDJjy/p/3285383.html
Copyright © 2011-2022 走看看