poj 1230 C++解法

考察点:贪心策略
思路:遍历每个column,如果这个column的wall数量n大于k,则抽掉其中n-k堵墙,抽掉墙的优先度按照墙横跨墙数超过k的column个数决定。

Source Code
Problem: 1230 Memory: 328K 
Time: 0MS     Language: C++ 
Result: Accepted 
Source Code

    #include <iostream>
    using namespace std;

    //#define DEBUG
    //1230
    int n,k,t, maxCol,maxIndex;
    int w[101][4];
    int cols[101][101];
    int walls[101][101];

    void init() {
    	int i,j,min,max;
    	for (j = 0; j < 101; j++) {
    		cols[j][0] = 0;
    		walls[j][0] = 0;
    	}
    	for (j = 0; j < n; j++) {
    		min = w[j][0] < w[j][2] ? w[j][0] : w[j][2];
    		max = w[j][0] > w[j][2] ? w[j][0] : w[j][2]; 
    		for (i = min; i <= max; i++) {
    			cols[i][++cols[i][0]] = j;
    			walls[j][++walls[j][0]] = i;
    		}
    	}
    }

    void printCols() {
    	int i,j;
    	cout << "start printCols()" << endl;
    	for (i = 0; i < 101; i++) {
    		if (cols[i][0] > 0) {
    			cout << "col: " << i << "\t wallNum: \t" << cols[i][0];
    			for (j = 1; j <= cols[i][0]; j++) {
    				cout << " " << cols[i][j];
    			}
    			cout << endl;
    		}
    	}
    	cout << "end printCols()" << endl;
    }
    void removeWall(int index) {
    	int i,j,colIndex;
    	for (i = 1; i <= walls[index][0]; i++) {
    		colIndex = walls[index][i];
    		for (j = 1; j <= cols[colIndex][0]; j++) {
    			if (cols[colIndex][j] == index) {
    				cols[colIndex][j] = cols[colIndex][cols[colIndex][0]];
    				cols[colIndex][0]--;
    				break;
    			}
    		}
    	}
    }

    int findMax() {
    	int i;
    	int max = cols[0][0];
    	maxIndex = 0;
    	for (i = 1; i <= maxCol; i++) {
    		if (cols[i][0] > max) {
    			max = cols[i][0];
    			maxIndex = i;
    		}
    	}
    	return max;
    }

    int wallScore(int index) {
    	int i;
    	int c = 0;
    	for (i = 1; i <= walls[index][0]; i++) {
    		if (cols[walls[index][i]][0] > k) {
    			c++;
    		}
    	}
    	return c;
    }

    void process() {
    	int i, j, maxWall, maxWallIndex, ws, delta;
    	int c = 0;
    	init();
    	#ifdef DEBUG
    			printCols();
    #endif
    	for (i = 0; i <= maxCol; i++) {
    		
    		//printCols();
    		if (cols[i][0] > k) {
    			delta = cols[i][0] - k;
    			c += delta;
    			//cout << endl << "c: " << c << endl;
    			while (delta--) {
    				maxWall = wallScore(cols[i][1]);
    				maxWallIndex = cols[i][1];
    				for (j = 2; j <= cols[i][0]; j++) {
    					ws = wallScore(cols[i][j]);
    					if (ws > maxWall) {
    						maxWall = ws;
    						maxWallIndex = cols[i][j];
    					}
    				}
    				removeWall(maxWallIndex);
    			}
    		}
    	}
    	cout << c << endl;
    }

    int main(int argc, char *argv[])
    {
    	int i,j;
    	cin >> t;
    	for (i = 0; i < t; i++) {
    		cin >> n >> k;
    		maxCol = 0;
    		for (j = 0; j < n; j++) {
    			cin >> w[j][0] >> w[j][1] >> w[j][2] >> w[j][3];
    			if (w[j][2] > maxCol) {
    				maxCol = w[j][2];
    			}
    		}

    		
    		process();
    	}
        return 0;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值