20170402"尚学堂杯"哈尔滨理工大学第七届程序设计竞赛ABCDFG题解

第一次参加个人赛

想着自己太辣稽肯定不能拿最佳新人

最后A了3题

实在是太辣稽了

A题 组合数取模 因为以为是很难的数学题就没做 我好智障...

B题 思维题 一开始太不谨慎了wa了几发...

C题 走台阶问题 因为没意识到数组初始赋值错了 一直错到比赛结束都不知道怎么回事 我好智障...

D题 简单Floyd 比赛时没读懂题意 赛后知道是Floyd实在是好气啊(捂脸痛哭)

F题 简单字符串模拟

G题 二进制 我竟然水过了

_______________________________________________________

Astonishing Combinatorial Number
Time Limit: 8000 MSMemory Limit: 512000 K
Total Submit: 56(11 users)Total Accepted: 14(9 users)Rating:Special Judge: No
Description

The combinatorial number CmnCnm in combinatorics, where it gives the number of the ways, disregarding order,

the m objects can be chosen from among n objects; more formally, the number of m-element subsets (or m-combinations)

of an n-element set.

Now, there's a simple problem about this number:

For three given number n, m and k, how many pairs of (i, j) will make the equation A.a be true. (0 <= i <= n, 0 <= j <= min(i, m))

Equation A.1:

Cjimodk=0Cijmodk=0

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases.

For each test case:
The first line contains two integers t(1<=t<=10^4) and k(1<=k<=30).
Each of the next t lines contains two integers n(1<=n<=2000) and m(1<=m<=2000) .


Output
Each test case should contain t lines. Each line has an integer indicate the answer of the problem.

Sample Input
2
1 2
3 3
2 5
4 5
6 7
Sample Output

1

0

7

Hint
In first test case, onlyC12=2C21=2 is multiple of 2.
Source
"尚学堂杯"哈尔滨理工大学第七届程序设计竞赛
题意:给出n m k 求Cij mod k的方案数


思路:首先预处理(打表),然后统计方案数。

1

1  1

1  2  1

1  3  3  1

...................

#include
  
  
   
   
#include
   
   
    
    
#include
    
    
     
     
using namespace std;
int c[2005][2005];
int main()
{
	int T;
	int t,k;
	while(~scanf("%d",&T))
		while(T--)
		{
			scanf("%d%d",&t,&k);
			memset(c,0,sizeof(c));
			c[0][0]=1%k;
			for(int i=1;i<2005;i++)
			{
				c[i][0]=1%k;
				c[i][i]=1%k;
			}

			for(int i=1;i<2005;i++)
				for(int j=1;j
     
     
    
    
   
   
  
  


Blind Father
Time Limit: 1000 MSMemory Limit: 512000 K
Total Submit: 131(57 users)Total Accepted: 66(54 users)Rating:Special Judge: No
Description

Mr. Leng, who is the predominately inheritor of buried-love family (One of the most vogue families during your primary school maybe, anyway, this is unimportant), has such cool, cooler and coolest temperament. But, only a good ACMer can be the real leader, in other words, be admitted as a successor.

One day, a problem come to Mr. Leng 's father about carpentry. There are N pieces of planks upright the ground in one line. Each one width 1 and height uncertain. His father wants to cut some of them and then get a rectangle. How the biggest rectangle does him can make? It too difficult to his father to solve the problem, but it is really easy for Mr. Leng. So do you. Please surmount the problem as soon as you can.

Ps: You can't move or change the posture or position of any planks.

Input

There are multiple cases. In each cases, the first line only contains an integer N,

means the number of the planks. And the second line contains N numbers, means the height of N planks one by one.

1<=N<=10000



Output
Please output the biggest rectangle that Mr. Leng 's father can get.
Sample Input
3
10 6 10
Sample Output
18
Hint
样例图形
Source
"尚学堂杯"哈尔滨理工大学第七届程序设计竞赛
题意:给出n个木板(可当成矩形) 选取连续的一部分木板(可以是一块或多块木板)经过切割后(有可能不用切割)得到一个矩形 求可得到的矩形的最大值


思路:暴力搜时间复杂度为O(n^2)会超时

            在遍历的时候以当前木板为一段连续木板中最短的一块木板,以此为中心往左右遍历搜索最长的连续木板,因为切割木板的话一定是以最短的木板为基准对其他木板进行             切割,所以每次只要遍历到长度大于等于当前木板的木板就行了。


#include<cstdio>
#include<iostream>
using namespace std;
int a[10005];
int main()
{
   int n;
   while(~scanf("%d",&n))
   {
      for (int i=1;i<=n;i++)
        scanf("%d",&a[i]);
      int m=0;
      for (int i=1;i<=n;i++)
      {
         int l=i-1,r=i+1;
         int ins=1;
         while(l>=1)
            if (a[i]<=a[l]) { l--; ins++; }
            else break;
         while(r<=n)
            if (a[i]<=a[r]) { r++; ins++; }
            else break;
        m=max(m,ins*a[i]);
      }
      printf("%d\n",m);
   }
}


Collection Game
Time Limit: 1000 MSMemory Limit: 128000 K
Total Submit: 123(50 users)Total Accepted: 54(47 users)Rating:Special Judge: No
Description
POI and POJ are pair of sisters, one is a master in “Kantai Collection”, another is an excellent competitor in ACM programming competition. One day, POI wants to visit POJ, and the pace that between their homes is made of square bricks. We can hypothesis that POI’s house is located in the NO.1 brick and POJ’s house is located in the NO.n brick. For POI, there are three ways she can choose to move in every step, go ahead one or two or three bricks. But some bricks are broken that couldn’t be touched. So, how many ways can POI arrive at POJ’s house?

Input

There are multiple cases.

In each case, the first line contains two integers N(1<=N<=10000) and M (1<=M<=100), respectively represent the sum of bricks, and broke bricks. Then, there are M number in the next line, the K-th number a[k](2<=a[k]<=n-1) means the brick at position a[k] was broke.

Output
Please output your answer P after mod 10007 because there are too many ways.
Sample Input

5 1

3

Sample Output
3
Source
"尚学堂杯"哈尔滨理工大学第七届程序设计竞赛
题意:有n个台阶,有m个坏了,求走上第n个台阶的方案数(从第一个台阶开始走)


思路:只要把坏了的台阶的步数赋值为0就可以了

           递推公式f(x)=f(x-1)+f(x-2)+f(x-3)

#include<cstdio>
#include<cstring>
#define mod 10007
int f[10005];
int v[10005];
int main()
{
   int n,m;
   int a;
   while(~scanf("%d%d",&n,&m))
   {
      memset(v,0,sizeof(v));
      f[2]=1;
      f[3]=2; f[4]=4;
      for (int i=1;i<=m;i++)
      {
        scanf("%d",&a);
        v[a]=1;
      }
      f[4]-=( (v[2]+v[3])==0 ? 0 : ( (v[2]+v[3])==1?2:3 ) );
      f[3]-=( v[2]?f[2]:0 );
      for (int i=5;i<=n;i++)
      {
         if (v[i]) { f[i]=0; continue; }
         f[i]=( ( v[i-1]?0:f[i-1] ) + ( v[i-2]?0:f[i-2] ) + ( v[i-3]?0:f[i-3] ) )%mod;
      }
      printf("%d\n",f[n]%mod);
   }
}

Distinct Package Manager
Time Limit: 1000 MSMemory Limit: 512000 K
Total Submit: 124(32 users)Total Accepted: 35(23 users)Rating:Special Judge: No
Description

On Linux or OSX, we can install software by package manager. For example, apt-get in Ubuntu/Debian, yum in Fedora/CentOS and brew in OSX. All of them are great software-package manager.

You determined to design your own software-package manager. The inevitable thing is you should solve dependences of these software-packages.

• If package A depends package B, you should install package B before installing package A.

• If you want to uninstall package B, then you must uninstall package A.

Now, you already know all the dependences of all these software-packages. You can assume that 0-package don’t depend any other package. And all dependence-relationship won’t form a circle. Of course, no package depend itself.

Your uses want to know how many packages’ install state will be changed when installing or uninstalling a package.

NOTE: Install an installed package and uninstall an uninstalled package won’t change any packages’ state.


Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases.

The first line of each test cases contains an integer n(1<=n<=100), indicating the number of software-packages.

For each software-package(except 0-package) contains two lines, the first line contains an integer mi, indicating the number of dependences of i-package. The next mi integers indicating the serial numbers of dependences.

The next line contains an integer q(1<=q<=200), indicating the number of queries.

Each of the next q liens contains a string s and an integer k, indicating the action and serial number of software-package. s must be one of "install" and "uninstall".

Output
For each query, output a line contains the number of changed packages.
Sample Output
1
2
1
0
2
install 1
uninstall 0
Hint
2
2
Source
"尚学堂杯"哈尔滨理工大学第七届程序设计竞赛
题意:给出软件包的依赖关系 求安装或卸载包所需要的操作次数


思路:根据依赖关系A依赖于B可得,安装时先安装A在安装B 卸载时先卸载B再卸载A

           要注意的是已安装的不用安装,已卸载(或根本没安装)的不用卸载即用一个数组记录包的安装状态(安装或未安装)最后遍历求操作总数

           (要是能读懂题意的话 我。。)

#include<cstdio>
#include<cstring>
using namespace std;
int a[105][105];
int v[105];
int main()
{
   int t;
   int n,q;
   while(~scanf("%d",&t))
   while(t--)
   {
      scanf("%d",&n);
      memset(a,0,sizeof(a));
      memset(v,0,sizeof(v));
      for (int i=1;i<=n-1;i++)
      {
         int x,y;
         scanf("%d",&x);
         for (int j=1;j<=x;j++)
         {
            scanf("%d",&y);
            a[y][i]=1;
         }
      }
      for (int i=0;i<=100;i++)
        for (int j=0;j<=100;j++)
          for (int k=0;k<=100;k++)
           if (a[j][i]==1&&a[i][k]==1)
             a[j][k]=1;

      scanf("%d",&q);
      for (int i=1;i<=q;i++)
      {
         char op[15];
         int x;
         scanf("%s%d",op,&x);
         if (op[0]=='i')
         {
            if (v[x]) { puts("0"); continue; }
            v[x]=1;
            int num=0;
            for (int j=0;j<=100;j++)
             if (a[j][x]==1&&!v[j]) num++,v[j]=1;
            printf("%d\n",num+1);
         }
         if (op[0]=='u')
         {
            if (!v[x]) { puts("0"); continue; }
            v[x]=0;
            int num=0;
            for (int j=0;j<=100;j++)
             if (a[x][j]==1&&v[j]) num++,v[j]=0;
            printf("%d\n",num+1);

         }
      }
   }
}

Final Ugly English
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 146(58 users)Total Accepted: 76(56 users)Rating:Special Judge: No
Description

ACM twist-toy encountered such a problem in the work, this article, to ensure that this article only lowercase letters

and spaces, please send the articles in each word inverted output, such as "hello world this is an competition". You

should output "olleh dlrow siht si na noititepmoc".

Input

A group of data, each line of data input from the lower case letters and spaces of the article, the length of not more than

one thousand

Output
Output a line for each word after the reversal of the article.
Sample Input
hello world this is an competition
Sample Output
olleh dlrow siht si na noititepmoc
Source
"尚学堂杯"哈尔滨理工大学第七届程序设计竞赛
题意:看输入输出就知道了......


思路:简单模拟


#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
#define M(x) memset(x,0,sizeof(x))
#define N 100005
#define inf 0x3f3f3f
#define For(n) for (int i=1;i<=n;i++)
using namespace std;
int main()
{
   char a[1005],b[1005];
   M(a); M(b);
   while(gets(a))
   {
      int n=strlen(a);
      int p=0;
      for (int i=0;i<=n-1;i++)
      {
         if (a[i]>='a'&&a[i]<='z')
            b[p++]=a[i];
         if (a[i]==' ')
         {
            reverse(b,b+p);
            p=0;
            printf("%s",b);
            putchar(' ');
            M(b);
         }
      }
      if (a[n-1]>='a'&&a[n-1]<='z')
      {
        reverse(b,b+p);
        printf("%s\n",b);
        M(b);
      }
   }
}

Great Atm
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 178(34 users)Total Accepted: 63(30 users)Rating:Special Judge: No
Description
An old story said the evil dragon wasn’t evil at all, only bewitched, and now that the riddles were solved it was proving to be as kind as its new master.
A powerful warrior Atm is going to solve the riddles. First, he should beat the evil wizard. The road from Atm’s castle to wizard’s lab is filled with magic traps. The magic trap will affect Atm’s combat effectiveness.
Atm’s combat effectiveness can be considered as an integer. Effect of magic trap can be considered as mathematical operation. The three kinds of magic traps correspond to three kind of bit operation. (AND, OR and XOR)
Atm can adjust his equipment to change his initial combat effectiveness from 0 to m (include 0 and m). He wants when he arrives the wizard’s lab, his combat effectiveness can be maximum.
Input
There are multiple test cases.
For each test cases:
The first line contains two integers n(1<=n<=10^5) and m(1<=m<=10^9), indicating the number of magic traps and the maximum of initial combat effectiveness.
Each of the next n lines contains a string and an integer, indicating the bit operation. The string will be “AND”, “OR” or “XOR” correspond to AND operation (&), OR operation (|) or XOR operation (^). The integer t(1<=t<=10^9) is second operand in the operation.

Output
For each test cases, a line contains an integer, indicating the maximum combat effectiveness when he arrives the wizard's lab.
Sample Input
3 10
AND 5
OR 6
XOR 7
Sample Output
1
Source
"尚学堂杯"哈尔滨理工大学第七届程序设计竞赛
题意:给出一个数m,m可以从0~m变化(不定值),求m经过一系列位运算后的最大值


思路:把m分为奇偶数两种情况,然后水过,经测试这种做法不严谨且有bug

           学长们的严谨做法是用二进制计算 求出答案x(假设最大值为x)的每一个二进制位的最大值(0或1)最终得出答案


#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
   int n;
   long long m;
   while(~scanf("%d%lld",&n,&m))
   {
      long long ma=m-1;
      for (int i=1;i<=n;i++)
      {
         char op[4];
         long long num;
         scanf("%s%lld",op,&num);
         if (op[0]=='A') m&=num,ma&=num;
         if (op[0]=='O') m|=num,ma|=num;
         if (op[0]=='X') m^=num,ma^=num;
      }
      printf("%lld\n",max(m,ma));
   }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值