2015年秋hit校赛(我目前所解决的三道题)

  其实早就想把自己会的校赛题目总结一下,但是这段时间事情很多,刚考完英语翻译,想到这段时间把学习的重心都放在ACM上,所以是时候把最近写的一些题总结一下。先说说校赛吧:和ACM正式比赛一样,一共10道题目全英文。其实现在来看我现在会的这三道题,其实难度还称不上ACM、但是自己在比赛的时候很紧张,IDE一报错就慌了,调了半天才找到错误,结果一提交又发现爆内存了。总之,很失败地只做出了一道题。

A题:A×B problem

Description

I have a very simple problem for you. Given two matrixes A and B, your job is to calculate the result of A * B. I assure you that every number will be less than 2^10 and greater than zero.

In matrix multiplication, if C = A * B, cij = ∑aik*bkj(1≤k≤m). In this problem, A contains n rows and m columns, and B contains m rows and p columns, so it will always be a legal operation.

Input

    At the first line, there is an integer T (T ≤ 233), which shows the number of test cases.

    At each case, there will be 3 lines. The first line contains 3 integers n, m and p(1 ≤ n, m, p ≤ 20), indicates the size of matrix A and B. The second line contains n * m numbers includes a11, a12, …, a1m, …, an1, an2, …, anm in order. In the same way, the third line contains m * p numbers includes b11, b12, …, b1m, …, bn1, bn2, …, bnm in order.

Output

For each case, print n*k numbers —if matrix C = A * B, print c11, c12, …,c1k, …, cn1, cn2, …, cnk in order.

Sample

Input

1

2 2 2

1 2 3 4

4 3 2 1

Output

8 5 20 13

分析:只不过是简单的矩阵乘法而已,自己在写的时候数组长度一开始弄得太大了。

代码:

#include <stdio.h>
#define N 20
int fun(int a[N][N],int b[N][N],int j,int k, int m)
{
    int i,sum=0;
    for(i=0;i<m;i++)
    {
        sum+=a[j][i]*b[i][k];
    }
    return sum;
}
int main()
{
   int num,i,j,k,n,m,p;
   int a[N][N],b[N][N],c[N][N];
   scanf("%d",&num);
   for(i=1;i<=num;i++)
   {
       scanf("%d%d%d",&n,&m,&p);
       for(j=0;j<n;j++)
           for(k=0;k<m;k++)
            scanf("%d",&a[j][k]);
       for(j=0;j<m;j++)
           for(k=0;k<p;k++)
            scanf("%d",&b[j][k]);
       for(j=0;j<n;j++)
       {
           for(k=0;k<p;k++)
           {
               c[j][k]=fun(a,b,j,k,m);
           }
       }
       for(j=0;j<n;j++)
       {
           for(k=0;k<p;k++)
           {
                if(j==n-1&&k==p-1)
                {
                    printf("%d
",c[j][k]);
                    break;
                }
               printf("%d ",c[j][k]);
           }
       }
   }
    return 0;
}

B题:A Good Day

Description

   Little Left and Little Right are two lovely and bright girls. Both of them want to have a good day with handsome PY.However PY is only want to play with one of them.So they have to play a simple game and only the winner could have a nice day with PY.

   The rules of the game are as follows:

   To begin with,there are N stones on the table.Little Left and Little Right take away the stones in turn. In each round , they won't be taken more than K stones away,and they have to take away at least one stone.The girl who take away the last stone would be the loser.And Little Left would take first.   

   Suppose that Little Left and Little Right are bright and they really want to play with PY.So they always take the best move and never make mistake.

   Now for the given N and K,please tell PY who will be so lucky to have a nice day with him.

Input

The first line contains a integer T, then T cases follows.

In each case, there are one lines of input. The line contains 2 integers N and K, means at first there are N stones on the table and each time they would not take more than K stones away.

1<=N<=10^7    1<=K<=10^7

Output

For each case, you should output the winner’s name.

Sample

Input

3

839 45

90 84

10 10

Output

Little Left

Little Left

Little Left

分析:看上去很复杂,其实只是很简单的博弈论。我们需要谨记题目说的一个条件那就是这两个人都是足够的聪明。可以分情况讨论:当N=1的时候,先拿必输,当N=2~k+1的时候后拿的都是必输。而当N=k+2的时候又是先拿必输……然后我们就可以发现一个规律:当Nmod(k+1)=1的时候,先拿都是必输。反之则后拿必输。那么程序其实就很简单了

代码:

#include <stdio.h>
int main()
{
   int T,N,K,i;
   scanf("%d",&T);
   for(i=1;i<=T;i++)
   {
       scanf("%d%d",&N,&K);
       if(N==1)
        printf("Little Right
");
       else if(N!=1&&N%(K+1)==1)
        printf("Little Right
");
       else
        printf("Little Left
");
   }
   return 0;

}

C题:IQ Text

Judge received an IQ test, maybe he is too busy to finish it.so can you help him?

The test is as follows: the person gets a piece of squared paper with a 4 × 4 square painted on it. Some of the square's cells are painted black and others are painted white. Your task is to repaint at most one cell the other color so that the picture has a 2 × 2 square, completely consisting of cells of the same color. If the initial picture already has such a square, the person should just say so and the test will be completed.

Your task is to write a program that determines whether it is possible to pass the test. You cannot pass the test if either repainting any cell or no action doesn't result in a 2 × 2 square, consisting of cells of the same color.

Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. Then T test cases follow. (T<=30)  . Then each four lines contain four characters each: the j-th character of the i-th line equals "." if the cell in the i-th row and the j-th column of the square is painted white, and "#", if the cell is black.

Output

Print "YES" (without the quotes), if the test can be passed and "NO" (without the quotes) otherwise.

Sample test(s)

Input

2

####
.#..
####
....

####
....
####
....

Output

YES

NO

Note

In the first test sample it is enough to repaint the first cell in the second row. After such repainting the required 2 × 2 square is on the intersection of the 1-st and 2-nd row with the 1-st and 2-nd column.

分析:一开始以为是图论就被吓得不敢做了,后来一问大神们,才知道只不过是一个遍历搜索而已。但是自己在敲的时候也遇到了一些麻烦,尤其是在如何判断这个2*2正方形是不是颜色可以变为相同。后来参考了一下别人的代码,发现了一种很简便的转化,就是转化为单纯的数字而已。不过用的是CPP,感觉CPP的确是竞赛必须学会的。

代码:

#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
    int T;
    char str[4][5];
    scanf("%d",&T);
    for(;T>0;T--)
    {
        bool ans=false;
        for(int i=0;i<4;i++)
            scanf("%s",str[i]);
        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
                str[i][j]=str[i][j]=='.'?0:1;       //把'.'转换为0,'#'转化为1
        for(int i=1;i<4;i++)
            for(int j=1;j<4;j++)
                ans|=(str[i][j]+str[i-1][j-1]+str[i-1][j]+str[i][j-1])!=2 ;   //如果可以转化则只可能每个正方形的三个或以上的点相同,不能为2
        if(ans)
            printf("YES
");
        else
            printf("NO
");
    }
    return 0;
}

现在想想这些题的确很水,可以看做签到题。。。还有七道题还没有思路,已有思路就发上来。

原文地址:https://www.cnblogs.com/kugwzk/p/5070136.html