ACM 省赛题 求算法

ice_cream 2012-05-22 07:48:59
加精
(1) Magic Sequence

Ivankevin loves sequences.

A sequence of n + m elements is called a MAGIC SEQUENCE it.
1. Each elements ai (1 <= i <= n + m ) is +1 or -1.
2. There are total n “+1”s and m “-1”s.
3. For every j ( 1 <= j <= n + m), we have the sum of ai (1 <= i <= j ) is nonnegative.

Now given n and m, Ivankevin wants to know the number of magic sequences consists of n “+1”s and m “-1”s.

Input
The first line is an integer T, the number of test cases.
Each case is a line of two integers n and m, 1 <= n,m <= 100.
Output
For each case ,print an integer x, which is the number of magic sequences modulo 100000007.

Sample Input
2
2 1
3 3
Sample Output
2
5


(2) The largest Arrow

Three points A(x1 ,y1), B(x2,y2), and C(x3,y3) form an arrow if and only if the following conditions are fulfilled:
x1 = x3 < x2
y1 < y2 < y3

The length of the arrow (x2 - x1) must not shorter than the width of the arrow y3 - y1 .
Figure 3.1 shows an example of an arrow. We define the size of an arrow as its length plus its width . Given N points in the plane, what’s the largest possible arrow can be formed from three of the given points ?



Input:
The first line of the input contains a positive integer T specifying the number of test cases to follow.
The fist line each test case contains a positive integer N ( 1 <= N <= 2000 ). Then follows N lines ,each describes a point with coordinates (xi, yi). ( 0 <= xi, yi <= 107)
It’s assumed that no two points are at the same location.

Output:
For each test case you should output a single line containing “Case X : Y” ( quotes for clarity) where X is the number of the test case (starting at 1). Y is the size of the largest arrow in the plane. If there’s not any arrow in the plan, Y should be equal to -1.

Sample Input:
1
5
2 2
2 5
6 4
2 4
2 10
Sample Output
Case 1: 7

...全文
6651 62 打赏 收藏 转发到动态 举报
写回复
用AI写文章
62 条回复
切换为时间正序
请发表友善的回复…
发表回复
半山th 2013-04-26
  • 打赏
  • 举报
回复
我在线提交了,楼上各位的代码,都不能AC啊!谁有能AC的代码啊?
lyyyj123 2012-05-30
  • 打赏
  • 举报
回复
高手如云啊 强
ssd189 2012-05-28
  • 打赏
  • 举报
回复
第二题的, 但是是错的.
#include <stdlib.h>
#include <stdio.h>

typedef struct {
int x;
int y;
}Point;

Point newPoint(int x, int y) {
Point p;

p.x = x;
p.y = y;
return p;
}

int pointLess(Point p1, Point p2) {
if(p1.y < p2.y)
return 1;
else if(p1.y > p2.y)
return 0;
else if(p1.x <= p2.x)
return 1;
else
return 0;
}

//已经验证的有
//pA.y < pB.y < pC.y
//pA.x < pB.x
int sufficeArrow(Point pA, Point pB, Point pC) {
if(pA.x != pC.x)
return 0;
else if((pB.x - pA.x) < (pC.y - pA.y))
return 0;
else {
return 1;
}
}

int kindsOfArrowWithSortedPointsAndPointA_PointBFixed(
Point *points, int npoints, int pBIndex) {
int i, sum;
Point pA, pB;

pA = points[0];
pB = points[pBIndex];
sum = 0;
for(i = pBIndex + 1; i < npoints; ++i) {
Point pC;

pC = points[i];
if(pC.y == pB.y)
continue;
if(sufficeArrow(pA, pB, pC))
++sum;
}

return sum;
}

//points[0]是pA
int kindsOfArrowWithSortedPointsAndPointAFixed(Point *points, int npoints) {
int i, sum;
Point pA;

pA = points[0];
sum = 0;
for(i = 1; npoints - (i + 1) >= 1; ++i) {
Point pB;

pB = points[i];
if(pB.x <= pA.x || pB.y == pA.y)
continue;
else
sum += kindsOfArrowWithSortedPointsAndPointA_PointBFixed(points, npoints, i);
}
}

//points以纵坐标升序排列
int kindsOfArrowWithSortedPoints(Point *points, int npoints) {
int i, sum;

sum = 0;
for(i = 0; npoints - i >= 3; ++i) {
sum += kindsOfArrowWithSortedPointsAndPointAFixed(points + i, npoints - i);
}
}

int kindsOfArrow(Point *points, int npoints) {
int i;

for(i = 1; i < npoints; ++i) {
int j;
Point key;

key = points[i];
for(j = i - 1; j >= 0; --j) {
if(pointLess(key, points[j]))
points[j + 1] = points[j];
else break;
}
points[j + 1] = key;
}

return kindsOfArrowWithSortedPoints(points, npoints);
}

void doTest() {
int i, npoints, k;
Point *points;

npoints;
scanf("%d", &npoints);
points = malloc(sizeof(Point) * npoints);
for(i = 0; i < npoints; ++i) {
int x, y;

scanf("%d %d", &x, &y);
points[i] = newPoint(x, y);
}

k = kindsOfArrow(points, npoints);
printf("Output: %d\n", k);
}

int main() {
int N, i;

scanf("%d", &N);
for(i = 0; i < N; ++i)
doTest();

return 0;
}
ssd189 2012-05-28
  • 打赏
  • 举报
回复
第一题的:
#include <stdlib.h>
#include <stdio.h>

//n个+1, m个-1的MagicSequence的种类, 且前面数组之和为s(s>=0)
int kindsOfMagicSequenceWithFormer1(int n, int m, int s) {
int a, b;

if(m + n == 0)
return 1;

a = (n > 0)?kindsOfMagicSequenceWithFormer1(n - 1, m, s + 1):0;
b = (m > 0 && s - 1 >= 0)?kindsOfMagicSequenceWithFormer1(n, m - 1, s - 1):0;

return a + b;
}

//n个+1, m个-1的MagicSequence的种类
int kindsOfMagicSequence(int n, int m) {
if(n < m) return 0;
return kindsOfMagicSequenceWithFormer1(n, m, 0);
}

void doTest() {
int n, m, k;

scanf("%d %d", &n, &m);
k = kindsOfMagicSequence(n, m);
printf("Output: %d\n", k);
}

int main() {
int numOfCase, i;

scanf("%d", &numOfCase);
for(i = 0; i < numOfCase; ++i)
doTest();

return 0;
}
yishuangpangxie 2012-05-28
  • 打赏
  • 举报
回复
厉害,高手一点,少走半年
FelixLiu_5 2012-05-28
  • 打赏
  • 举报
回复
我也是来学习的,暂时只能围观
ssd189 2012-05-27
  • 打赏
  • 举报
回复
F(n, m) = F(n-1, m) + F(n, m-1)
这个公式是很有问题的. 第一题的.

lwouyang 2012-05-27
  • 打赏
  • 举报
回复
第二题的题意应该是说形成箭头要满足3个条件吧 ?!
1、x1 = x3 < x2
2、y1 < y2 < y3
3、width(y3 - y1) <= length(x2 - x1),也就是箭头尖的程度是有要求的。
LZ 的原文中 第三个条件 是文字叙述 不是数学式子,而且还跟前面两个隔开了一行,但从文意上来看应该是连续的。不知是不是我看错了! ^_^
因此(如果我没有看错题意的话),借用 litaoye 的表达方式,
像 x1 = 0,(1, 10000) x2 = 10,(2,6) 无法形成箭头,
像 x1 = 0,(1, 10) x2 = 10,(2,6) 则可以,
因此为预防这种意外,不能轻易删除那些较短的线段吧?
Payden 2012-05-26
  • 打赏
  • 举报
回复
果断很纠结啊
Sawyer 2012-05-25
  • 打赏
  • 举报
回复
用C写一个


#include "stdio.h"
#include "stdlib.h"
int arrow(int **array,int sum);
void show(int **array,int sum);
int find(int hight,int **array,int x,int sum);
int main(){
int total=0,cur=0;
int *final;
scanf("%d",&total);
final=(int*)malloc(total*sizeof(int));
while(cur<total){
int sum=0,i=0,j=0;
scanf("%d",&sum);
int **array;
array=(int**)malloc(sum*sizeof(int*));
while(i<sum){
array[i]=(int*)malloc(2*sizeof(int));
i++;
}
i=0;
while(i<sum){
scanf("%d %d",&array[i][j],&array[i][j+1]);
i++;
}
//show(array,sum);
int l=arrow(array,sum);
final[cur]=l;
cur++;
}
cur=0;
while(cur<total){
printf("%d",final[cur]);
cur++;
}
return 0;
}
int arrow(int **array,int sum){
int i=0,j=0,min_x=0,max_x=0,min_y=0,max_y=0;
int x=0,hight=0,size=0,maxsize=0,y=0;
while(i<sum){
x=array[i][0];
y=array[i][1];
while(i<sum){
if(array[i][0]==x && (array[i][1]-y)!=0){
hight=abs(array[i][1]-y);
size=find(hight,array,x,sum);
if(maxsize<size)
maxsize=size;
}
i++;
}
i++;
}
return maxsize;
}
void show(int **array,int sum){
int i=0,j=0;
while (i<sum) {
printf("%d %d\n",array[i][j],array[i][j+1]);
i++;
}
}
int find(int hight,int **array,int x,int sum){
int i=0;
while(i<sum){
if(array[i][0]>x && abs(array[i][0]-x)>hight)
return abs(array[i][0]-x+hight);
i++;
}
}
思想的浪潮 2012-05-25
  • 打赏
  • 举报
回复
果断连题目都未看懂
hklove 2012-05-24
  • 打赏
  • 举报
回复
这个不知道啊~~
bingo_ms 2012-05-24
  • 打赏
  • 举报
回复
。。就是很简单的枚举过程。。
不过常数的系数可能只有0.5左右。。2000的数据不知道要运行多久。
要求是1S吗?
[Quote=引用 34 楼 的回复:]
不知道你是怎么做的, 能说下吗, 学习下..


引用 31 楼 的回复:

感觉第二题算法O(n^2)的可以吗?
[/Quote]
gotoac 2012-05-24
  • 打赏
  • 举报
回复
在哪个oj上的题啊?
[Quote=引用 43 楼 的回复:]

省赛? 哪个省的? 浙江吗?
[/Quote]
gotoac 2012-05-24
  • 打赏
  • 举报
回复
省赛? 哪个省的? 浙江吗?
shangguangshuang 2012-05-24
  • 打赏
  • 举报
回复
想当年参加MCM,不过那是好多年前的事儿了,顶楼主
ice_cream 2012-05-24
  • 打赏
  • 举报
回复
不知道你是怎么做的, 能说下吗, 学习下..

[Quote=引用 31 楼 的回复:]

感觉第二题算法O(n^2)的可以吗?
[/Quote]
ice_cream 2012-05-24
  • 打赏
  • 举报
回复
通不过...

[Quote=引用 31 楼 的回复:]

感觉第二题算法O(n^2)的可以吗?
[/Quote]
bingo_ms 2012-05-24
  • 打赏
  • 举报
回复
感觉第二题算法O(n^2)的可以吗?
绿色夹克衫 2012-05-24
  • 打赏
  • 举报
回复
不是删除点,只是删除线段,并且是按照x排序后。比如存在x = 0,(1, 10000)这样的线段,那么x = 1,(2,6)这样的线段不就没用了么?因为任何一个可以组成箭头的组合,同x = 0的点组成的箭头,Size都要大于同x=1组成的箭头。同理在x相等的情况下,只需要取y的最大和最小值就可以了。

如果存在x = 0,(1, 10)这样的线段,x = 1,(2, 11),那么等价于 x = 0 (1, 10), x = 1 (10,11)。
如果存在x = 0,(2, 5)这样的线段,x = 1,(1, 10),那么等价于 x = 0 (2, 5), x = 1 (5,10)。 x = 1 (1,2) 这3条线。


[Quote=引用 41 楼 的回复:]

引用 15 楼 的回复:

先把点按照x排序,从中找出可以作为左边起点的点对pStart[i] pEnd[i]。这样就获得了k条线段,再对这k条线段做处理,让所有x' > x的线段不能遮住坐标为x的线段(删除遮……

这个存在一种可能性,比如 (1,10000),(1,5),(1,1),(6,2).如果按照你所说的要删除了(1,5)(1,1)组成的线段的化,就没有箭头可以生成了。
我……
[/Quote]
加载更多回复(28)

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧