【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;

}

 

你可能感兴趣的:(模拟)