您的位置:首页 > 理论基础 > 计算机网络

2011大连赛区网络赛 HDOJ

2011-09-04 18:07 465 查看
【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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: