【11/10】模拟赛

前言

第一次没写出全AC代码。

 

第一题 distinct

【题目描述】

陶陶为了给一道平面几何题出数据,需要产生 N 个点(x[i],y[i])。已知x,y是由伪随机函数顺序产生,即:
X[i+1] = (X[i]*Ax+Bx+i) mod Cx (X[1], Ax,Bx,Cx 是事先给定的)
Y[i+1] = (Y[i]*Ay+By+i) mod Cy (Y[1], Ay,By,Cy 是事先给定的)

这样,就可以快速连续产生很多点坐标(X[i], Y[i])。

不幸的是,这样产生的点有可能有相同的,虽然这种几率很少,但严谨的陶陶不允许这种事发生。陶陶要求你帮助他解决最少要产生前多少项时,正好有 N 个不相同的点。

 

【输入格式】

第一行。一个整数 N .

第二行:4个整数 X[1]、 Ax、Bx、Cx .

第三行:4个整数 Y[1]、 Ay、By、Cy .

 

【输出格式】

一个整数 M 。表示最少要连续产生 M 个点,正好有 N 个不相同的点。数据保证有答案。

 
【样例输入】

21

2 4 3 6

5 2 3 13

 

【样例输出】

24

 

【数据范围】

1<=N<=1,000,000, 其它所有数据都在[1...1,000,000,000]范围内。
 

【分析】

AC代码我不会。

有两个同学用HASH写的,但是我改写成CPP后还是超时。简直就是拼人品的题目。

代码是30分的二叉搜索树。

 

第二题 Allbarns

【题目描述】

农民约翰打算建一个新的矩形谷仓。但是,矩形谷仓的4个角落不能在落在软土路基上,只能落在一些固定点上。现在,他已经找到地面上有N(4 <= N <= 1,000)个点,角落只可以落在这些点上。他想知道依次每加多一个点,可以建立新谷仓的方法数量,请你帮助他找到答案。

 

【输入格式】

第1行:一个整数,N

第2行至N +1行:每行有两个被空格分隔的整数的x,y,作为一个点的坐标。

所有的x,y都不会超过16,000。所有点都是不同的。

 

【输出格式】

共 N 行:每行表示当前可以建立的新的谷仓的数目。

 

【样例输入】

8
1 2
1 -2
2 1
2 -1
-1 2
-1 -2
-2 1
-2 –1

 

【样例输出】

0
0
0
0
0
1
3
6

 

【分析】

AC代码我也不会。

我的代码是N^4的。但是过了7个点。枚举两个点,向量乘法判断直角,然后枚举第四个点。

 

第三题 cubes

【题目描述】

FJ和Best用 N (1 <= N <= 30,000)块相同的小立方块玩游戏,小方块编号为1..N。开始时,小方块都单独分开的,每个看成一个柱子,即有 N 柱子。FJ要Best做 P(1 <= P <= 100,000) 个操作,操作有两种类型:

(1) FJ要求Best把X号方块所在的柱子放到Y号所在的柱子上面,成一个新柱子。

(2)FJ要求Best计算X号方块所在柱子,它下面有多少个小方块。

请编个程序,帮助Bet计算。

 

【输入格式】

第一行:一个整数 P

第2..P+1行:第i+1行表示第i个FJ要求的合法操作。如果这行以'M'开头,后面有两个整数 X,y 表示要进入(1)操作。 如果这行以'C'开头,后面有一个整数 X,表示要求计算X所在柱子下面的方块个数。

注:所有操作都是合法的。N 并没有出现在输入文件中。

 

【输出格式】

依次要求计算的值,每次一行。

 

【样例输入】

6

M 1 6

C 1

M 2 4

M 2 6

C 3

C 4

 

【样例输出】

1

0

2

 

【分析】

并查集。

before[x]是x上面有多少个数。count[x]代表集合个数。

 

第四题 friend

【题目描述】

有一个镇有N个居民。当然其中有许多人是朋友的关系。根据有名的谚语:“我朋友的朋友也是我的朋友”,所以如果A和B是朋友,B和C是朋友,那么A和C也是朋友。

你的任务是算出在这个镇中最大的朋友集团为多少人。

 

【输入格式】

输入文件的第一行有2个正整数 N 和 M 。N代表镇上居民的数目(1 <= N <= 30000 ),M 代表这些居民中朋友关系的数目( 0 <= M <= 30000)。接下来的M行每行有2个整数A,B( 1 <= A,B <= N , A不等于B),代表A,B为朋友关系。这M行中可能有的会重复出现。

 

【输出格式】

输出文件仅一行,在这个镇中最大的朋友集团为多少人。

 

【样例输入】

10 12
1 2
3 1
3 4
5 4
3 5
4 6
5 2
2 1
7 10
1 2
9 10
8 9

 

【样例输出】

6

 

【分析】

比第三题简单的并查集。

 

代码

第一题

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXN 1000010
#define mmm 10000000
long long n,m,lx,ly,xx,yy,ax,bx,cx,ay,by,cy;
int tot,root;
struct tn {
  int left,right;
  long long x,y;
} t[MAXN];
bool ins(int *x) {
  if (*x == 0) {
    *x = ++tot;
    t[*x].left = t[*x].right = 0;
    t[*x].x = xx;
    t[*x].y = yy;
    return 1;
  } else {
      if (t[*x].x == xx && t[*x].y == yy)
        return 0;
      if (xx < t[*x].x)
        return ins(&t[*x].left);
      if (xx == t[*x].x) {
        if (yy < t[*x].y)
          return ins(&t[*x].left);
        return ins(&t[*x].right);
      }
      if (xx > t[*x].x)
        return ins(&t[*x].right);
    }
}
int main() {
  freopen("distinct.in","r",stdin);
  freopen("distinct.out","w",stdout);
  scanf("%lld",&n);
  scanf("%lld%lld%lld%lld%lld%ld%lld%lld",&lx,&ax,&bx,&cx,&ly,&ay,&by,&cy);
  --n;
  xx = lx;
  yy = ly;
  ins(&root);
  while (n) {
    ++m;
    xx = (lx * ax + bx + m) % cx;
    yy = (ly * ay + by + m) % cy;
    if (ins(&root))
      --n;
    lx = xx;
    ly = yy;
  }
  printf("%lld\n",m + 1);
  return 0;
}

 

第二题

#include <stdio.h>
#define MAXN 1000
struct ss {
  int x,y;
} a[MAXN];
int n,ans,x1,y1,x2,y2,tx,ty;
bool check(int x1,int y1,int x2,int y2) {
  return x1 * x2 + y1 * y2 == 0;
}
int main() {
  freopen("allbarns.in","r",stdin);
  freopen("allbarns.out","w",stdout);
  scanf("%d",&n);
  for (int i = 1;i <= n;++i) {
    scanf("%d%d",&a[i].x,&a[i].y);
    for (int j = 1;j < i;++j) {
      x1 = a[j].x - a[i].x;
      y1 = a[j].y - a[i].y;
      for (int k = j + 1;k < i;++k) {
        x2 = a[k].x - a[i].x;
        y2 = a[k].y - a[i].y;
        if (check(x1,y1,x2,y2)) {
          tx = a[i].x + x1 + x2;
          ty = a[i].y + y1 + y2;
          for (int t = 1;t < i;++t)
            if ((a[t].x == tx) && (a[t].y == ty)) {
              ++ans;
              break;
            }
        }
      }
    }
    printf("%d\n",ans);
  }
  return 0;
}

 

第三题

#include <stdio.h>
#include <stdlib.h>
#define maxn 30010
int root[maxn],before[maxn],count[maxn];
int n,x,y;
char c;
int froot(int x) {
  if (!root[x])
    return x;
  int te = froot(root[x]);
  before[x] = before[root[x]] + before[x];
  root[x] = te;
  return te;
}
void merge(int x,int y) {
  int rx = froot(x),ry = froot(y);
  if (rx == ry)
    return;
  root[rx] = ry;
  before[rx] += count[ry];
  count[ry] += count[rx];
}
int main() {
  freopen("cubes.in","r",stdin);
  freopen("cubes.out","w",stdout);
  for (int i = 1;i <= 30000;++i)
    count[i]=1;
  scanf("%d",&n);
  scanf("%c",&c);
  for (int i = 1;i <= n;++i) {
    scanf("%c",&c);
    if (c=='M') {
    scanf("%d%d",&x,&y);
    merge(y,x);
    } else {
        scanf("%d",&x);
        int te = froot(x);
        printf("%d\n",count[te] - before[x] - 1);
      }
    scanf("%c",&c);
  }
  return 0;
}

 

第四题

#include <stdio.h>
#define MAXN 30010
int fr[MAXN],cou[MAXN];
int n,m,x,y,ans;
int froot(int x) {
  if (!fr[x])
    return x;
  int te = froot(fr[x]);
  fr[x] = te;
  return te;
}
void mer(int x,int y) {
  int rx = froot(x),ry = froot(y);
  fr[ry] = rx;
  cou[rx] += cou[ry];
}
int main() {
  freopen("friend.in","r",stdin);
  freopen("friend.out","w",stdout);
  scanf("%d%d",&n,&m);
  for (int i = 1;i <= n;++i)
    cou[i] = 1;
  for (int i = 1;i <= m;++i) {
    scanf("%d%d",&x,&y);
    int rx = froot(x),ry = froot(y);
    if (rx != ry)
      mer(x,y);
  }
  for (int i = 1;i <= n;++i)
    if ((!fr[i]) && (cou[i] > ans))
      ans = cou[i];
  printf("%d\n",ans);
  return 0;
}

 

posted @ 2010-11-10 15:38  Sephiroth.L.  阅读(531)  评论(0编辑  收藏  举报