2019中山大学程序设计竞赛(重现赛)

因为太菜,我们队只做对了四题,还是要继续加油啊。

1002

Triangle

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7179    Accepted Submission(s): 856

Problem Description

After Xiaoteng took a math class, he learned a lot of different shapes, but Xiaoteng's favorite triangle is because he likes stable shapes, just like his style. 

After the Xiaoxun knew it, he wanted to give a triangle as a gift to Xiaoteng. He originally planned to do one, but he was too tired. So he decided to bring some wooden sticks to Xiaoteng and let Xiaoteng make a triangle himself. 

One day, Xiaoxun brought n sticks to Xiaoteng. Xiaoteng wanted to try to use three of them to form a triangle, but the number is too much, Xiaoteng stunned, so he can only ask for your help.

Input

There are mutiple test cases.

Each case starts with a line containing a integer  n(1≤n≤5×106)  which represent the number of sticks and this is followed by n positive intergers(smaller than 231−1) separated by spaces.

Output

YES or NO for each case mean Xiaoteng can or can't use three of sticks to form a triangle.

Sample Input

4

1 2 3 4 

Sample Output

YES


解法:就是给出n个棍子,求有没有三条棍子能够组成三角形。n的范围太大,直接用循环来遍历找的话,两层循环就会爆时间了,由于是多组数据所以单层循环的话也会爆。其实也就是Fib数列的应用,Fib数列的那些项是刚好不能组成三角形的临界值,而边长的范围2^31也就是Fib的45项内的样子,如果多于50个棍子则说明存在棍子不在Fib数列的那些项里,打破了临界值,则一定是有三个棍子可以组成三角形的,直接输出YES即可。而对于小于50个棍子的,则可以单层遍历来找,先对所有棍子从小到大排一下序,a[i-1]<a[i]<a[i+1],根据三角形成立的三条边关系及排完序的大小关系,只要a[i - 1] + a[i] > a[i + 1]则这三个棍子是可以组成三角形的。

代码:

#include<bits/stdc++.h>
using namespace std;
int n, a[5000010];
int main() {
  while(~scanf("%d", &n)) {
    for (int i = 0 ; i < n; i++)
      scanf("%d", a + i);
    if(n > 50) puts("YES");
    else {
      sort(a, a + n);
      int flag = 0;
      for (int i = 1; i < n - 1; i++) {
        if(a[i - 1] + a[i] > a[i + 1]) {
          flag = 1;
          break;
        }
      }
      if(flag) puts("YES");
      else
        puts("NO");
    }
  }
  return 0;
}

 

1004

Monitor

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 163840/163840 K (Java/Others)
Total Submission(s): 872    Accepted Submission(s): 145

 

Problem Description

Xiaoteng has a large area of land for growing crops, and the land can be seen as a rectangle of n×m. 

But recently Xiaoteng found that his crops were often stolen by a group of people, so he decided to install some monitors to find all the people and then negotiate with them.

However, Xiao Teng bought bad monitors, each monitor can only monitor the crops inside a rectangle. There are p monitors installed by Xiaoteng, and the rectangle monitored by each monitor is known. 

Xiao Teng guess that the thieves would also steal q times of crops. he also guessed the range they were going to steal, which was also a rectangle. Xiao Teng wants to know if his monitors can see all the thieves at a time.

 

Input

There are mutiple test cases.

Each case starts with a line containing two integers n,m(1≤n,1≤m,n×m≤107) which represent the area of the land.

And the secend line contain a integer p(1≤p≤106) which represent the number of the monitor Xiaoteng has installed. This is followed by p lines each describing a rectangle. Each of these lines contains four intergers x1,y1,x2 and y2(1≤x1≤x2≤n,1≤y1≤y2≤m) ,meaning the lower left corner and upper right corner of the rectangle.

Next line contain a integer q(1≤q≤106) which represent the number of times that thieves will steal the crops.This is followed by q lines each describing a rectangle. Each of these lines contains four intergers x1,y1,x2 and y2(1≤x1≤x2≤n,1≤y1≤y2≤m),meaning the lower left corner and upper right corner of the rectangle.

 

Output

For each case you should print q lines.

Each line containing YES or NO mean the all thieves whether can be seen.

 

Sample Input

6 6 
3 
2 2 4 4 
3 3 5 6 
5 1 6 2 
2 
3 2 5 4 
1 5 6 5

 Sample Output

YES
NO

Hint

In the picture,the red solid rectangles mean the monitor Xiaoteng installed, and the blue dotted rectangles mean the area will be stolen.


解法:差分+二维前缀和。

代码:

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define llinf 1ll<<60
using namespace std;
typedef long long ll;
int read() {
  int x = 0, f = 1;
  int ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + (int)(ch - '0');
    ch = getchar();
  }
  return x * f;
}
void out(ll a) {
  if (a < 0) {
    putchar('-');
    a = -a;
  }
  if (a >= 10) {
    out(a / 10);
  }
  putchar(a % 10 + '0');
}
int n, m, p, q, x1, y, x2, y2;
int main() {
  while(~scanf("%d%d", &n, &m)) {
    int num[n+5][m+5];
    for (int i = 0; i <= n; i++) 
      for (int j = 0; j <= m; j++)
        num[i][j] = 0;
    p = read();
    for (int i = 0; i < p; i++) {
      x1 = read(), y = read(), x2 = read(), y2 = read();//对[x1,y]到[x2,y2]矩形区域进行覆盖 
      num[x1][y]++, num[x2+1][y2+1]++, num[x1][y2+1]--, num[x2+1][y]--;
    }
    for (int i = 1; i <= n; i++) 
      for (int j = 1; j <= m; j++) 
        num[i][j] += num[i-1][j] + num[i][j-1] - num[i-1][j-1];//每个位置被覆盖的次数 
    for (int i = 1; i <= n; i++) 
      for (int j = 1; j <= m; j++)
        if (num[i][j]) num[i][j] = 1;//为了方便算矩形区域的面积,将只要被覆盖了的位置都置为1 
    //如果要求某个矩形区域内是否全部被覆盖到了,可以通过算面积与二维前缀和是否相等来判断,如果全部覆盖则该二维区域的和必定等于该二维区域的长*宽
    for (int i = 1; i <= n; i++) 
      for (int j = 1; j <= m; j++) 
        num[i][j] += num[i-1][j] + num[i][j-1] - num[i-1][j-1];//再算一遍整个01矩阵的二维前缀和 
    q = read();
    while (q--) {
      x1 = read(), y = read(), x2 = read(), y2 = read();
      int cnt = num[x2][y2] - num[x1-1][y2] - num[x2][y-1] + num[x1-1][y-1];//该矩形内所有位置的和,也就是被覆盖的位置数量 
      if ((x2-x1+1)*(y2-y+1) == cnt) printf("YES\n");
      else
        printf("NO\n");
    } 
  }
  return 0;
}

 

1005

Coding Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4171    Accepted Submission(s): 779

Problem Description

Here is the logic.I am the brother of mata Chuang.Mata chuang is the brother of cxk.So what am I?Am I the grand-brother of cxk?Or am I in a position that same brother level of cxk?Or cxk is the grand-brother of me?
Fine,it doesn't matter to the problem.Problem can't be a problem until it has description.But description are just words.Meaningless words.So,we treat words miserably like this, given a string s consist of 3*n lowercase letter.The binary ascii string of s is a string consist of 8*3*n 0-1 string(one char,8bits,The lower significnt bit is in the front, the higher is in the back.). We want you output the binary ascii string.But we don't want the string too long.So we want you put every 6 bit together(The higher significnt bit is in the front, the lower is in the back.) and output the corresponding array,with a length of 8*3*n/6.Please check the sample for specific. 

Input

one line,one string. (n<=1e5)

Output

one line,4*n integer representing the target array.

Sample Input

abc 

Sample Output

33 36 27 6

Hint

s=abc binary ascii string=10000110 01000110 11000110 answer binary array=100001 100100 011011 000110 final answer array=33 36 27 6


代码:

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
int arr[8];
int getVal(string s) {
  int sum = 0;
  for (int i = 0; i < 6; i++) {
    sum += pow(2,5-i)*(s[i]-'0');
  }
  return sum;
}
string getBinary(int x) {
  int k = 0;
  memset(arr,0,sizeof(arr));
  while (x) {
    arr[k++] = x%2;
    x /= 2;
  }
  string s = "";
  for (int i = 0; i < 8; i++) {
    s += char('0'+arr[i]);
  }
  return s;
}
int main() {
  string s;
  cin >> s;
  string ans = "";
  int len = s.length();
  int temp;
  for (int i = 0; i < len; i++) {
    temp = s[i];
    ans += getBinary(temp);
  }
  vector<int> v;
  for (int i = 0; i < ans.length(); i+=6)
    v.push_back(getVal(ans.substr(i,6)));
  for (int i = 0; i < v.size(); i++)
    cout << v[i] << " ";
  return 0;
}

 

1008

Clumsy Keke

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1199    Accepted Submission(s): 595

Problem Description

Keke is currently studying engineering drawing courses, and the teacher has taught her how to find its volume through the three views of the part. But her brain doesn't work well that she can't find the volume of complex parts. So she needs your help.

To simplify the problem, the part is made up of cubes with side length 1, and the vertices of these cubes are all on the grid. Give you three 0/1 matrices, each representing each of the three views. 0 means that there is no projection of cubes at this position of the view; 1 means that there is a projection of cubes at this position of the view.

Now Keke wants you to help her find the volume of the part determined by the three views.

Input

There are mutiple test cases, the number of which is no more than 10. For each test case:

The first line of input contains three integers mx,my,mz(1≤mx,my,mz≤99) , which represent the coordinate range of all possible cubes (i.e. all possible cubes are in the cuboid area whose body diagonal is from (1,1,1) to (mx,my,mz)).

Following input a 0/1 matrix with mx lines and my columns representing the front view, and the y-th column of the x-th row represents the projection of all the cubes in the front view such as (x,y,?).

Following input a 0/1 matrix with my lines and mz columns representing the side view, and the z-th column of the y-th row represents the projections of all the cubes in the side view such as (?,y,z).

Following input a 0/1 matrix with mz lines and mx columns representing the top view, and the x-th column of the z-th row represents the projection of all the cubes of the top view such as (x,?,z).

The '?' in the above coordinates represents any integer. Numbers in the same line are separated by spaces. For more detailed input information, please see the sample.

Output

For each test case:

The first line of output should contain an integer, representing the volume of the part determined by the three views. If the determined part is not unique, find the largest of all possible parts.

Keke's teacher promises that there is at least one part that satisfies the input.

Sample Input

5 6 4
1 1 1 1 1 1
0 0 0 1 0 1
0 0 0 1 0 1
0 0 0 0 0 1
0 0 0 0 0 1
0 1 1 0
1 0 0 1
0 0 0 1
0 0 0 1
0 0 0 1
1 1 1 1
1 0 0 0 0
1 0 0 0 0
1 0 0 0 0
1 1 1 1 1

Smple Output

17

Hint


题意:就是说有一个立体的东西由单位方块组成,给出它的三个面的形状,1代表该处有单位方块,0代表没有,求这个立体最多有多少个单位方块。

解法:开一个三维数组,分别根据给出的三个面来进行填充,一个面上,有1的区域就假设该区域后面全都是1(即后面全都是单位方块),最后遍历这个三维数组,如果某一处被三个面都确认了为1则该处可以有单位方块,统计这样的数量就是答案了。至于怎么判断是否被三个面都确认了,可以用值来判断,某处每被一个面确认则+1,被三个面都确认了则值为3。

代码:

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define llinf 1ll<<60
using namespace std;
typedef long long ll;
int x, y, z, ans;
int Map1[110][110], Map2[110][110], Map3[110][110];
int Map[110][110][110];
int read() {
  int x = 0, f = 1;
  int ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + (int)(ch - '0');
    ch = getchar();
  }
  return x * f;
}
void out(ll a) {
  if (a < 0) {
    putchar('-');
    a = -a;
  }
  if (a >= 10) {
    out(a / 10);
  }
  putchar(a % 10 + '0');
}
int main() {
  while(~scanf("%d%d%d", &x, &y, &z)) {
    ans = 0;
    for(int i = 1; i <= x; i++) {
      for(int j = 1; j <= y; j++) {
        Map1[i][j] = read();
      }
    }
    for(int i = 1; i <= y; i++) {
      for(int j = 1; j <= z; j++) {
        Map2[i][j] = read();
      }
    }
    for(int i = 1; i <= z; i++) {
      for(int j = 1; j <= x; j++) {
        Map3[i][j] = read();
      }
    }
    for(int i = 1; i <= x; i++) {
      for(int j = 1; j <= y; j++) {
        for(int k = 1; k <= z; k++) {
          Map[i][j][k] = Map1[i][j];
        }
      }
    }
    for(int i = 1; i <= y; i++) {
      for(int j = 1; j <= z; j++) {
        for(int k = 1; k <= x; k++) {
          Map[k][i][j] += Map2[i][j];
        }
      }
    }
    for(int i = 1; i <= z; i++) {
      for(int j = 1; j <= x; j++) {
        for(int k = 1; k <= y; k++) {
          Map[j][k][i] += Map3[i][j];
        }
      }
    }
    for(int i = 1; i <= x; i++) {
      for(int j = 1; j <= y; j++) {
        for(int k = 1; k <= z; k++) {
          if(Map[i][j][k] == 3) ans++;
        }
      }
    }
    printf("%d\n", ans);
  }
  return 0;
}

 

1009 

Enlarge it

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3267    Accepted Submission(s): 1123

Problem Description

Taotao is glad to see that lots of students have registered for today's algorithm competition. Thus he wants to pull a banner on the wall. But Taotao is so stupid that he doesn't even know how to enlarge words to fit the size of banner. So Taotao gives you a slogan template and asked you to enlarge them in k times.

Input

There are multiple test cases.
For each test case, first line contains three numbers n, m, k (1<=n, m<=100,1<=k<=10).
The next n lines each contain m visible characters.

Output

For each test case, you should output k*n lines each contain k*m visible characters to represent the expanded slogan.

Sample Input

3 3 2 
.*. 
.*. 
.*.

Sample Output

..**.. 
..**.. 
..**.. 
..**.. 
..**.. 
..**..

题意:就是给出一个矩阵图形,输出将其放大k倍后的图形。

代码:

#include<bits/stdc++.h>
using namespace std;
char Map[105][105];
int n, m, k;
int main() {
  while(~scanf("%d%d%d", &n, &m, &k)) {
    for(int i = 0; i < n; i++)
      for(int j = 0; j < m; j++)
        cin >> Map[i][j];
    for(int i = 0; i < n*k; i++) {
      for(int j = 0; j < m; j++) {
        for(int p = 0; p < k; p++) {
          printf("%c", Map[i/k][j]);
        }
      }
      printf("\n");
    }
  }
  return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值