USACO holstein, hamming

微博: http://t.sina.com.cn/g7tianyi

豆瓣:http://www.douban.com/people/Jackierasy/

廣度優先搜索的好題,廣搜的好處之一就是往往可以直接找到最短路徑,而且,就本題而言,還可以大規模剪枝。

優化的話估計還可以用位運算,那樣最後一組數據應該也可以在0s內AC掉。

 

/*
ID: fairyroad
TASK:holstein
LANG:C++
*/
//#define DEBUG
#include<deque>
#include<fstream>
#include<iostream>
using namespace std;
ifstream fin("holstein.in");
ofstream fout("holstein.out");

typedef deque<int> Queue;
int V, G;
int vitamin[25];
int fertilizer[15][25];
struct node
{
	Queue currsum, path;
	node() : currsum(0), path(0) {}
	node(const deque<int>& cs, const deque<int>& p) : currsum(cs), path(p) {}
};

#ifdef DEBUG
inline void printnode(const node& nd)
{
    cout<<"currsum :  ";
    for(size_t i = 0; i < nd.currsum.size(); ++i) cout<<nd.currsum[i]<<' ';
    cout<<"\npath :  ";
    for(size_t i = 0; i < nd.path.size(); ++i) cout<<nd.path[i]<<' ';
    cout<<"\n";
}
#endif

inline bool check(const Queue& sum)
{
	for(int i = 0; i < V; ++i)
		if(sum[i] < vitamin[i]) return false;

	return true;
}

inline void addi(Queue& sum, int index)
{
    for(size_t i = 0; i < sum.size(); ++i)
        sum[i]+=fertilizer[index][i];
}

int main()
{
	fin>>V;
	for(int i = 0; i < V; ++i) fin>>vitamin[i];
	fin>>G;
	for(int i = 0; i < G; ++i)
		for(int j = 0; j < V; ++j)
			fin>>fertilizer[i][j];

	deque<node> Q;
	Queue start_sum(V,0), start_path;
	//start_sum.push_back(0);
	start_path.push_back(-1); // for initilization, don't fell wierd
	Q.push_back(node(start_sum, start_path));
	while(!Q.empty())
	{
        node n = Q.front();
        #ifdef DEBUG
            printnode(n);
        #endif

        for(int i = n.path.back()+1; i < G; ++i)
        {
            Queue tmpsum(n.currsum), tmppath(n.path);
            addi(tmpsum, i);
            tmppath.push_back(i);
            if(check(tmpsum))
            {
                fout<<tmppath.size()-1<<' ';
                for(size_t j = 1; j < tmppath.size()-1; ++j)
                    fout<<tmppath[j]+1<<' ';
                fout<<i+1 <<"\n";
                goto DONE;
            }
            Q.push_back(node(tmpsum, tmppath));
        }
        Q.pop_front();
	}

DONE:
	return 0;
}

 

 

hamming是水題,USACO對位運算的考察還是很全面的。但是位運算是基礎。


 

/*
ID: fairyroad
TASK:hamming
LANG:C++
*/

#include<fstream>
using namespace std;
ifstream fin("hamming.in");
ofstream fout("hamming.out");

int N, B, D;
int res[64];
// return the number of 1 in the binary representation of the xor of a and b
inline int counthd(int a, int b)
{
    int count = 0, n = a^b;
    while(n)
    {
        n &= (n-1);
        ++count;
    }
    return count;
}

int main()
{
    fin>>N>>B>>D;
    int num = 1;
    for(int i = 1; num <= N && i <= (1<<B)-1; ++i)
    {
        bool flag = true;
        for(int j = 0; j < num; ++j)
            if(counthd(res[j], i) < D)
            {
                flag = false;
                break;
            }
        if(flag) res[num++] = i;
    }

    // output
    for (int i=0; i<N-1; i++) fout<<res[i]<<( ((i+1)%10==0)?"\n":" ");
    fout<<res[N-1]<<endl;
    return 0;
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章