【CJ】2016 Round1B

不得不说做题费劲了很多

CJ_GettingTheDigits

简单题,一开始我用了类似背包的动态规划,发现大数据太慢。

然后想到了用高斯消元,由于懒得写,想到了贪心

#include<iostream>
#include<vector>
#include<fstream>
#include<string>
#include<set>
#include<algorithm>

using namespace std;

class state
{
public:
    static state str2state(string& s)
    {
        state x;
        for (auto ch : s)
            x.a[static_cast<int>(ch - 'A')]++;
        return x;
    }
    state()
    {
        a = vector<int>(26,0);
    }
    friend bool operator<=(const state&, const state&);
    friend state operator-(const state&, const state&);
//private:
    vector<int> a;
};

vector<state> digit;

bool operator <= (const state& x, const state& y) 
{
    for (int i = 0; i < 26;i++)
    if (x.a[i] > y.a[i]) return false;
    return true;
}

state operator - (const state& x, const state& y) 
{
    state z = x;
    for (int i = 0; i < 26; i++)
        z.a[i] -= y.a[i];
    return z;
}

int main()
{
    vector<string> digit_string = { "ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE" };
    vector<int> c = {8,0,6,7,5,4,9,3,1,2};
    for (int i = 0; i < 10; i++)
    digit.push_back(state::str2state(digit_string[i]));

    int T;
    ifstream fin("in.txt");
    ofstream fout("out.txt");
    string s;
    s = "";
    fin >> T;
    for (int i = 0; i < T; i++)
    {
        string s;
        fin >> s;
        state x = state::str2state(s);
        
        fout << "Case #" << i+1 << ": ";
        string ans = "";
        for (int j = 0; j < 10; j++)
        {
            int i = c[j];
            while (digit[i] <= x)
            {
                ans = ans + static_cast<char>('0' + i);
                x = x - digit[i];
            }
        }
        sort(ans.begin(), ans.end());
        fout << ans << endl;
    }
    return 0;
}

CJ_Close Match

这道题隔夜了,一开始想法是先找一个必须不一样的位,然后找它前面第一个能更改的位,枚举这个位置的情况,然后这个位置前面全弄成一样的。

原来这是有bug的,下了一个标称fc以后发现了错误。

??9 6?1

比如这个,答案是599和601.

我的算法答案是609,611. 

今天中午吃好饭来改了一下,不找第一个能更改的位,而是枚举那个更改的位,其他一样,就好了。

#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<sstream>

using namespace std;

long long str2ll(string s)
{
    long long ret;
    stringstream ss;
    ss << s;
    ss >> ret;
    return ret;
}

bool vllLess(vector<long long>& v1, vector<long long>& v2)
{
    long long x1 = abs(v1[0] - v1[1]);
    long long x2 = abs(v2[0] - v2[1]);
    if (x1 < x2) return true;
    if (x1 > x2) return false;
    if (v1[0] < v2[0]) return true;
    if (v1[0] > v2[0]) return false;
    return v1[1] < v2[1];
}

vector<long long> vs2vll(vector<string> vs)
{
    stringstream ss;
    long long op1 = str2ll(vs[0]);
    long long op2 = str2ll(vs[1]);
    return vector<long long>{op1,op2};
}

vector<string> con(string s1, string s2, int d1, int d2)
{
    for (int i = 0; i < s1.length(); i++)
    {
        if (s1[i] == '?') s1[i] = (d1 ? '9' : '0');
        if (s2[i] == '?') s2[i] = (d2 ? '9' : '0');
    }
    return vector<string>{s1,s2};
}

vector<string> solve(string s1, string s2)
{
    vector<long long> retans;
    vector<string> ret;
    int d = 0;
    int N = s1.length();
    while (d < N && (s1[d] == '?' || s2[d] == '?' || s1[d] == s2[d])) d++;
    
    //cout << d << endl;
    
    if (d == N)
    {
        for (int i = 0; i < N; i++)
        {
            if (s1[i] == '?' && s2[i] == '?') s1[i] = s2[i] = '0';
            else
            {
                if (s1[i] == '?') s1[i] = s2[i];
                else s2[i] = s1[i];
            }
        }
        return (vector<string>{s1,s2});
    }

    if (!d)
    {
        if (s1[0] > s2[0]) return con(s1, s2, 0, 1);
        if (s1[0] < s2[0]) return con(s1, s2, 1, 0);
    }

    for (int dd = 0; dd < d; dd++)
    {
        auto ts1 = s1;
        auto ts2 = s2;
        for (int i = 0; i < dd; i++)
        {
            if (s1[i] == '?' && s2[i] == '?') s1[i] = s2[i] = '0';
            else
            {
                if (s1[i] == '?') s1[i] = s2[i];
                else s2[i] = s1[i];
            }
        }
        char st1 = '0';
        char st2 = '0';
        char en1 = '9';
        char en2 = '9';
        if (s1[dd] != '?') st1 = en1 = s1[dd];
        if (s2[dd] != '?') st2 = en2 = s2[dd];

        //cout << st1 << en1 << endl;
        //cout << st2 << en2 << endl;

        for (int i = st1; i <= en1; i++)
        for (int j = st2; j <= en2; j++)
        for (int k = 0; k <= 1; k++)
        {
            s1[dd] = i;
            s2[dd] = j;
            vector<string> tmp;
            if (k) tmp = con(s1, s2, 0, 1);
            else tmp = con(s1, s2, 1, 0);
            //cout << tmp[0] << "*" << tmp[1] << endl;
            auto tmpans = vs2vll(tmp);
            if (ret.empty() || vllLess(tmpans, retans))
            {
                retans = tmpans;
                ret = tmp;
            }
        }
        s1 = ts1;
        s2 = ts2;
    }
    return ret;
}

int main()
{
    ifstream fin("in.txt");
    ofstream fout("out.txt");
    int T;
    fin >> T;
    for (int t = 0; t < T; t++)
    {
        //cout << "case:" << t << endl;
        fout << "Case #" << t + 1 << ": ";
        string s1;
        string s2;
        fin >> s1 >> s2;
        auto z = solve(s1, s2);
        fout << z[0] << " " << z[1] << endl;
        //if (z[0] != z[1])
        //fout << s1 << " " << s2 << " " << z[0] << " " << z[1] << endl;
    }
    //system("pause");
    return 0;
}

CJ_Technobabble

这道题我一拿到就觉得是图论。瞬间想到等价于找最少多少个人就能覆盖所有的第一栏话题和第二栏话题。这样就是一个二分图的最小覆盖。

所以解决了,然后我又花了一下午搞到4点,我真是蠢炸了。匈牙利算法我还是不怎么懂,算了反正我会网络流,我还会贴模板。

#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>

using namespace std;

map<string, int> m1;
map<string, int> m2;


bool find(vector<vector<int>>& g, vector<int>& link, vector<bool>& vy,int st)
{
    for (auto x : g[st])
    {
        if (!vy[x])
        {
            vy[x] = true;
            if (link[x] == -1 || find(g,link,vy,link[x]))
            {
                link[x] = st;
                return true;
            }
        }
    }
    return false;
}

int maxMatch(int N1, int N2, vector<pair<int, int>> edge)
{
    auto g = vector<vector<int>>(N1, vector<int>{});
    for (auto x : edge)
    {
        g[x.first].push_back(x.second);
    }
    int ret = 0;
    auto link = vector<int>(N2, -1);

    for (int i = 0; i < N1; i++)
    {
        auto vy = vector<bool>(N2, false);
        if (find(g, link, vy, i)) ret++;
    }
    return ret;
}

int main()
{
    ifstream fin("in.txt");
    ofstream fout("out.txt");

    int T;
    fin >> T;
    for (int t = 0; t < T; t++)
    {
        fout << "Case #" << t + 1 << ": ";
        m1.clear();
        m2.clear();
        int M;
        fin >> M;
        int N1 = 0;
        int N2 = 0;
        vector<pair<int, int>> edge;
        for (int i = 0; i < M; i++)
        {
            string s1, s2;
            fin >> s1 >> s2;
            if (m1.find(s1) == m1.end()) m1[s1] = N1++;
            if (m2.find(s2) == m2.end()) m2[s2] = N2++;
            edge.push_back(make_pair(m1[s1], m2[s2]));
        }

        //fout << M << endl;
        fout << M - (N1 + N2 - maxMatch(N1, N2, edge)) << endl;
    }
    return 0;
    system("pause");
}

小小总结一下:

这是向T恤迈出的第一步,值得写个文章纪念一下。

我想算法的速度不快写的更慢,真是老了,还是要努力一下,争取拿到T恤!

posted @ 2016-05-27 16:07  syb3181  阅读(167)  评论(0编辑  收藏  举报