zoukankan      html  css  js  c++  java
  • 穷竭搜索: POJ 2718 Smallest Difference

    题目http://poj.org/problem?id=2718

    题意

    就是输入N组数据,一组数据为,类似 【1  4  5  6  8  9】这样在0~9之间升序输入的数据,然后从这些数据中切一刀,比如  n1:【1 4 5】,n2:【6 8 9】这样,然后 abs(n1- n2),对n1 和 n2的所有可能的排列 n1: 【1 4 5】【1 5 4】...这样,要算出来的最小的差,显然从中间切一刀才会出现这种解。

    题解

    这里可以用来练习 STL,算法不会也没有关系,可以在这题学到 bitset 的用法,类模板 bitset 表示一个 N 位的固定大小序列。可以用标准逻辑运算符操作位集,并将它与字符串和整数相互转换。如:bitset<10> used = static_cast<bitset<10>>(permute),10个二进制位, permute表示这个数的二进制表示形式;比如:permute=3; used就是 0000000011; used[0] = used[1] = 1; 这个低位在右边 

    我们这样,设输入字符串长度 len, 我们遍历 2 ^ len种可能,  used[i] == 1,则 s1 += line[i] ;否则 s2 += line[i];这样避免了  s1 = "1 4 5", s2 = "6 8 9" 或 s1 = "6 8 9", s2 = "1 4 5" 这种重复的情况。这样 s1, s2就被切割出来了。再对 s1, s2字符串的位置进行搜索, s1 = "123", "132"....这样 

    AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <cmath> 
    #include <bitset>
    using namespace std;
    
    int T;
    const int INF = 999999999;
    
    void solve()
    {
        scanf("%d", &T);
        getchar();        //下面输入 带空格的字符串, 需要吃掉输入T的回车,再可以
        while (T--)
        {
            string line;
            getline(cin, line);
            line.erase(remove(line.begin(), line.end(), ' '), line.end());      //擦除' '
            int ans = INF;
            int half = line.size() / 2;
            int len = line.size();
            int permute = 1 << len;    // 2 ^ len ; 
            
            do {
                //10个二进制位, permute表示这个数的二进制表示形式; permute=3; used就是 0000000011; 
                bitset<10> used = static_cast<bitset<10>>(permute);    // used[0] = used[1] = 1; 这个低位在右边 
    //            cout << "Debug: " << used << endl;                     //可以输出used看看 
                string s1, s2;
                for (int i = 0; i < len; i++)
                {
                    if (used[i])
                    {
                        s1 += line[i]; 
                    }
                    else 
                    {
                        s2 += line[i];
                    }
                }
                if ((s1.size() != half) || (s1[0] == '0' && s1.size() > 1))
                { 
                    continue;
                }
                //s1 s2已经被切割出来了
                //s1, s2字符串的位置进行搜索, s1 = "123", "132"....这样 
                do 
                {
                    int n1 = atoi(s1.c_str());
                    do {
                        if (s2[0] == '0' && s2.size() > 1) {
                            continue;
                        }
                        int n2 = atoi(s2.c_str());
                        int diff = abs(n1 - n2);
                        if (diff < ans) {
                            ans = diff;
                        }
                    } while (next_permutation(s2.begin(), s2.end()));
                } while(next_permutation(s1.begin(), s1.end()));
            } while (--permute);
            
            printf("%d
    ", ans);
        }   
        
    }
    
    int main()
    {
        solve();
        
        return 0;
    }
  • 相关阅读:
    CF741C.Arpa’s overnight party and Mehrdad’s silent entering [构造 二分图染色]
    CF719E. Sasha and Array [线段树维护矩阵]
    洛谷7月月赛
    CF666B. World Tour
    BZOJ4668: 冷战 [并查集 按秩合并]
    水题练习 2
    CF715B. Complete The Graph
    关于最短路、负环、差分约束系统的一点笔记
    关于最小生成树,拓扑排序、强连通分量、割点、2-SAT的一点笔记
    hdu1814 Peaceful Commission
  • 原文地址:https://www.cnblogs.com/douzujun/p/8510914.html
Copyright © 2011-2022 走看看