2011大连赛区网络赛 HDOJ

【HDU4001】


Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=4001


【思路】


DP。

按长和宽从小到大、d值从大道小排序。

dp[i] = max(block[i].c, dp[j]+block[i].c)。其中1<=j<i。

dp[j]+block[i].c表示当i可以叠加在j上面时的值。如果不可叠加就无需计算。

注意排序中的d值。

还需要注意dp数组用整型会溢出。


【代码】


#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 1000;

struct block
{
	int a;
	int b;
	int c;
	int d;
}b[maxn+5];

bool cmp(const block &a, const block &b)
{
	if (a.a!=b.a) return a.a<b.a;
	else if (a.b!=b.b) return a.b<b.b;
	else return a.d>b.d;
}

inline __int64 max(__int64 a, __int64 b)
{
	if (a>=b) return a;
	else return b;
}

__int64 dp[maxn+5];

int main()
{
	int n;
	int i, j;
	while(scanf("%d", &n)!=EOF)
	{
		if (n==0) break;
		for (i=0; i<n; i++)
		{
			scanf("%d %d %d %d", &b[i].a, &b[i].b, &b[i].c, &b[i].d);
			if (b[i].a<b[i].b)
			{
				int t = b[i].a;
				b[i].a = b[i].b;
				b[i].b = t;
			}
		}
		sort(b, b+n, cmp);
		for (i=0; i<n; i++)
			dp[i] = b[i].c;
		for (i=0; i<n; i++)
		{
			for (j=0; j<i; j++)
			{
				if (b[i].d==0)
				{
					if (b[i].a>=b[j].a && b[i].b>=b[j].b)
						dp[i] = max(dp[i], dp[j]+b[i].c);
				}
				else if (b[i].d==1)
				{
					if ((b[i].a>=b[j].a && b[i].b>b[j].b) || (b[i].a>b[j].a && b[i].b>=b[j].b))
						dp[i] = max(dp[i], dp[j]+b[i].c);
				}
				else
				{
					if (b[i].a>b[j].a && b[i].b>b[j].b)
						dp[i] = max(dp[i], dp[j]+b[i].c);
				}
			}
		}
		__int64 ans = -1;
		for (i=0; i<n; i++)
		{
			if (dp[i]>ans)
				ans = dp[i];
		}
		printf("%I64d\n", ans);
	}
	return 0;
}



【HDU4002】


Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=4002


【思路】


数学题。

化简式子结果为质数从小到大相乘直到刚好不大于所给的数时的数。

可以先把质数相乘结果保存起来,60以内的质数相乘即可达到100位以上。

对于给定的数字扫描找出所须答案。


【代码】


#include <iostream>
#include <cstring>
using namespace std;

char num[54][120] = 
{
        "2",
        "6",
        "30",
        "210",
        "2310",
        "30030",
        "510510",
        "9699690",
        "223092870",
        "6469693230",
        "200560490130",
        "7420738134810",
        "304250263527210",
        "13082761331670030",
        "614889782588491410",
        "32589158477190044730",
        "1922760350154212639070", 
        "117288381359406970983270",
        "7858321551080267055879090",
        "557940830126698960967415390",
        "40729680599249024150621323470",
        "3217644767340672907899084554130",
        "267064515689275851355624017992790",
        "23768741896345550770650537601358310",
        "2305567963945518424753102147331756070",
        "232862364358497360900063316880507363070",
        "23984823528925228172706521638692258396210",
        "2566376117594999414479597815340071648394470",
        "279734996817854936178276161872067809674997230",
        "31610054640417607788145206291543662493274686990",
        "4014476939333036189094441199026045136645885247730",
        "525896479052627740771371797072411912900610967452630",
        "72047817630210000485677936198920432067383702541010310",
        "10014646650599190067509233131649940057366334653200433090",
        "1492182350939279320058875736615841068547583863326864530410",
        "225319534991831177328890236228992001350685163362356544091910",
        "35375166993717494840635767087951744212057570647889977422429870",
        "5766152219975951659023630035336134306565384015606066319856068810",
        "962947420735983927056946215901134429196419130606213075415963491270",
        "166589903787325219380851695350896256250980509594874862046961683989710",
        "29819592777931214269172453467810429868925511217482600306406141434158090",
        "5397346292805549782720214077673687806275517530364350655459511599582614290", 
        "1030893141925860008499560888835674370998623848299590975192766715520279329390",
        "198962376391690981640415251545285153602734402721821058212203976095413910572270",
        "39195588149163123383161804554421175259738677336198748467804183290796540382737190",
        "7799922041683461553249199106329813876687996789903550945093032474868511536164700810",
        "1645783550795210387735581011435590727981167322669649249414629852197255934130751870910",
        "367009731827331916465034565550136732339800312955331782619462457039988073311157667212930",
        "83311209124804345037562846379881038241134671040860314654617977748077292641632790457335110",
        "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190",
        "4445236185272185438169240794291312557432222642727183809026451438704160103479600800432029464270",
        "1062411448280052319722448549835623701226301211611796930357321893850294264731624591303255041960530",
        "256041159035492609053110100510385311995538591998443060216114576417920917800321526504084465112487730",    
        "64266330917908644872330635228106713310880186591609208114244758680898150367880703152525200743234420230"
};

int ct[54] = {1,1,2,3,4,5,6,7,9,10,12,13,15,17,18,20,22,24,25,27,29,31,33,35,37,39,41,43,45,47,
49,51,53,56,58,60,62,64,66,69,71,73,76,78,80,82,85,87,89,92,94,97,99,101};//先把上面结果的长度存起来效率会有所提高

int main()
{
	char str[500];
	int t;
	int i;
	int x, y;
	scanf("%d", &t);
	while(t--)
	{
		scanf("%s", str);
		x = strlen(str);
		for (i=0; i<54; i++)
		{
			y = ct[i];
			if (x<y) break;
			else if (x>y) continue;
			else if (strcmp(str, num[i])<0) break;
		}
		printf("%s\n", num[i-1]);
	}
	return 0;
}



【HDU4004】


Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=4004


【思路】


二分。

上届为L,下界为相邻位置的距离的最大值。

注意要先排序。


【代码】


#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 500000;

int pt[maxn+5];

inline int solve(int mid, int l)
{
	int i = 0;
	int ct = 0;
	int cur = 0;
	while(cur<l)
	{
		cur += mid;
		while(cur>=pt[i+1])
			i++;
		cur = pt[i];
		ct++;
	}
	return ct;
}

int main()
{
	int l, n, m;
	int i;
	int left, right, mid, t;
	int ans;
	while(scanf("%d %d %d", &l, &n, &m)!=EOF)
	{
		for (i=1; i<=n; i++)
			scanf("%d", &pt[i]);
		pt[0] = 0;
		pt[n+1] = l;
		pt[n+2] = INT_MAX;
		sort(pt, pt+n+2);
		left = 0;
		for (i=1; i<=n+1; i++)
		{
			if (pt[i]-pt[i-1]>left)
				left = pt[i] - pt[i-1];
		}
		right = l;
		ans = INT_MAX; 
		while(left<=right)
		{
			mid = (left+right)/2;
			t = solve(mid, l);
			if (t<=m)
			{
				right = mid - 1;
				ans = mid;
			}
			else
			{
				left = mid + 1;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}



【HDU4006】


Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=4006


【思路】


最小堆。

用最小堆维护最大的k个值。

插入时,如果堆个数未满k个,则直接插入;

如果已满,则如果该数比堆最小的数大,则替换并对堆进行维护,如果比最小的数还小,则无需插入。


【代码】


#include <iostream>  
#include <cstring>  
using namespace std; 
 
int minheap[100005], lenmin; 
 
void exchange(int &a, int &b)  
{  
    int t=a;  
    a = b;  
    b = t;  
}   

void min_heap_insert(int v)//×îС¶ÑµÄ²åÈë  
{  
    lenmin++;  
    minheap[lenmin] = v;  
    int i=lenmin;  
    while(i>1 && minheap[i/2]>minheap[i])  
    {  
        exchange(minheap[i/2], minheap[i]);  
        i /= 2;  
    }  
}  

void min_heapify(int i)//×îС¶ÑµÄά»¤  
{  
    int l = 2*i, r = 2*i+1, smallest;  
    if (l<=lenmin && minheap[l]<minheap[i])  
    {  
        smallest = l;  
    }  
    else  
    {  
        smallest = i;  
    }  
    if (r<=lenmin && minheap[r]<minheap[smallest])  
    {  
        smallest = r;  
    }  
    if (smallest!=i)  
    {  
        exchange(minheap[i],minheap[smallest]);  
        min_heapify(smallest);  
    }  
} 

int main()  
{  
	int n, k;
	int i;
	int x;
	char s[4];
	while(scanf("%d %d", &n, &k)!=EOF)
	{
		lenmin = 0;
		for (i=0; i<n; i++)
		{
			scanf("%s", s);
			if (s[0]=='I')
			{
				scanf("%d", &x);
				if (lenmin<k)
				{
					min_heap_insert(x);
				}
				else
				{
					if (x>minheap[1])
					{
						minheap[1] = x;
						min_heapify(1);
					}
				}
			}
			else
			{
				printf("%d\n", minheap[1]);
			}
		}
	}
    return 0;  
} 



【HDU4007】


Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=4007


【思路】


坐标离散化。

由于点的规模只有1000个,而坐标范围太大,所以需要离散化点。

对于存在的xy坐标值保存起来。假如有ctx个x坐标,cty个y坐标。

如果(x,y)有点,则标为1,否则为0。然后用sum[x][y]数组保存该点到(0,0)点所成矩阵的点个数和。

然后枚举新的ctx*cty的矩阵。

对于矩阵中的每一个点,将其作为area的右下顶点,利用sum可以计算其再 r 的范围内的点个数。

记录其最大值即为答案。


【代码】


#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

const int maxn = 1000;

int sum[maxn+5][maxn+5];
int x[maxn+5], y[maxn+5];
int ctx, cty;

struct point
{
	int x;
	int y;
}pt[maxn+5];


inline int max(int a, int b)
{
	if (a>=b) return a;
	else return b;
}

int main()
{
	map<int, int> px, py;
	int n, r;
	int i, j;
	point temp;
	while(scanf("%d %d", &n, &r)!=EOF)
	{
		for (i=0; i<n; i++)
		{
			scanf("%d %d", &pt[i].x, &pt[i].y);
		}
		for (i=0; i<n; i++)
		{
			x[i+1] = pt[i].x;
			y[i+1] = pt[i].y;
		}
		sort(x+1, x+n+1);
		sort(y+1, y+n+1);
		px.clear();
		py.clear();
		for (i=1,ctx=0; i<=n; i++)
		{
			if (px.find(x[i])==px.end())
			{
				ctx++;
				px[x[i]] = ctx;
				x[ctx] = x[i];
			}
		}
		for (i=1,cty=0; i<=n; i++)
		{
			if (py.find(y[i])==py.end())
			{
				cty++;
				py[y[i]] = cty;
				y[cty] = y[i];
			}
		}
		memset(sum, 0, sizeof(sum));
		for (i=0; i<n; i++)
		{
			sum[px[pt[i].x]][py[pt[i].y]] = 1;
		}
		for (i=1; i<=ctx; i++)
		{
			for (j=1; j<=cty; j++)
			{
				sum[i][j] += sum[i][j-1] + sum[i-1][j] - sum[i-1][j-1];
			}
		}
		int sx = 1;
		int sy = 1;
		int ans = 0;
		for (i=1; i<=ctx; i++)
		{
			while(x[sx]+r<x[i])
				sx++;
			sy = 1;
			for (j=1; j<=cty; j++)
			{
				while(y[sy]+r<y[j])
					sy++;
				ans = max(ans, sum[i][j]-sum[sx-1][j]-sum[i][sy-1]+sum[sx-1][sy-1]);
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}


你可能感兴趣的:(网络,struct,insert,360,Exchange,iostream)