您的位置:首页 > 运维架构

TopCoder Srm671 一二题翻译及题解

2016-02-15 19:36 344 查看
第1题
染色(paint)

现有W*H的棋盘格子,要在其上用蓝色染其中的一些格子,形成一个蓝色的矩形。由于费用问题,你最多只能染色M个格子,请问你能染色的矩形最大面积是多少?

【输入格式】(paint.in)

第1行:2个整数W和H,范围在[1…10^6]。

第2行:1个整数M,范围在[1…10^12]。

【输出格式】(paint.out)

一个整数,可能的矩形最大面积。

【输入输出样例】

输入
输出
3
5

14

12

4
4

10

9

1000000
1000000

999999999999

999999000000

【分析】
这显然是一道很简单的题,但是我交的时候竟然错了三次,有一次是因为没有考虑到M>W*H的情况,有两次是因为没有去掉测试的语句。这一道题最直观的思路就是枚举所有的W和H,求出所有的面积,并取一个小于M又最大的情况。不过显然可以观察到只需枚举W或H即可,因为M/W就是以当前的W为一边的最大又不超过M的矩形面积的另一边长度。当然,还要判断一下M/W是否超过H,如果超过就不行了,就放不下了。当然要注意另一点:当M>W*H时,怎样枚举都是找不出来的,则直接输出W*H就好了。
【代码】
# include <cstdio>
# include <iostream>
using namespace std;
unsigned long long int w,h;
unsigned long long int m,i;
unsigned long long int MaxAns = 0;
int main(){
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout);
ios::sync_with_stdio(false);
cin >> w >> h;
cin >> m;

if (w * h <= m){
cout << w * h << endl;
return 0;
}
for (i=1;i<=w;++i){
if (MaxAns < (m/i)*i && m/i <= h){
MaxAns = (m/i)*i;
}
}
cout << MaxAns << endl;
}


[/code]

第2题
飞镖(dart)

小明喜欢玩飞镖游戏,他会把每次的得分都记录在数组中。今天有个飞镖大奖,得奖的规则是:如果你4次飞镖的得分先后是(a,b,c,d),满足a*b*c = d 。

小明准备把记录里的其他项删除,只留下满足获奖条件的4个分数,他想问你有多少种不同方案?

【输入格式】(dart.in)

第1行:1个整数N。

第2行:N个整数,每个整数范围在[1…10^6]。

【输出格式】(dart.out)

一个整数,方案数。

【输入输出样例】

输入

输出

6

10
2 2 7
40 160

2

注:(10,2,2,40)、(2,2,40,160)

8

128
64 32 16
8 4 2 1

0

21

2 3 4
5 6 8 12 16
20 24 40
24 20 16
12 8 6
5 4 3 2
3

【N范围】

80%在[4…500],

100%在[4…2000]。

【分析】
这一道题最基本的解法(最直观的)是枚举a,b,c,并判断a*b*c是否在数组中存在,这可以用一个计数排序的思想(或者哈希表)用O(1)的时间判定a*b*c是否存在(还要判定a*b*c是否小于10^6),就可以过80%的数据。而满分算法,则是找到a*b和d/c的对应性,因为若a*b=d/c,则a*b*c=d,所以可以得出一个O(n^2)的题解。
只不过要注意一点:在联赛的时候,因为系统的不同,scanf对于Linux与Windows中long long的读入所用的方式是不同的。举个例子,假如a是long long,用scanf读入时,在Linux下是scanf("%lld",&a);,Windows下是scanf("%I64d",&a);。考试时要注意这个不同。

【代码】
# include <cstdio>
using namespace std;
const int MAXN = 2000;
const int Pow10_6 = 1000000;
int show[Pow10_6 + 2];
int num[MAXN + 1];
int main(){

freopen("dart.in","r",stdin);
freopen("dart.out","w",stdout);

int n;
long long Ans = 0;
scanf("%d",&n);
for (int i=0;i!=n;++i){
scanf("%d",&num[i]);
}

for (int i=2;i!=n;++i){		//Find b
for (int j=i-2;j>=0;--j){
//Find a
if ((long long )num[i-1] * (long long)num[j] <= Pow10_6){
//Could Put Inside(Means May Have a Number d that a*b*c=d)
++show[(long long)num[i-1] * (long long)num[j]];
}
}

for (int j=i+1;j!=n;++j){
//Find d
if (num[j] % num[i] == 0){
Ans += show[num[j] / num[i]];
}
}
}

printf("%I64d\n",Ans);
}


[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: