# 第八届福建省大学生程序设计竞赛

Problem A Frog

## Problem Description

Therearex frogs and y chicken in a garden. Kim found there are n heads and m legs in the garden. Please tell Kim how many frogs and chicken are there. (A frog has 4 legs, and a chicken has 2 legs.)

## Input

First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.

For each test case: Two number n and m.

1<=n, m <=100000. The data is legal.

## Output

For each test case, output two numbers A and B – the number of frog and the number of chicken.

22 62 4

## Sample Output

1 10 2

AC代码：

#include <iostream>
using namespace std;
int main()
{
int T;
cin>>T;
int n,m;
while(T--)
{
cin>>n>>m;
int t = ((4*n)-m)/2;
cout<<n-t<<" "<<t<<endl;
}
return 0;
}


Problem B Triangles

## Problem Description

This is a simple problem. Given two triangles A and B, you should determine they are intersect, contain or disjoint. (Public edge or point are treated as intersect.)

## Input

First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.

For each test case: X1 Y1 X2 Y2 X3 Y3 X4 Y4 X5 Y5 X6 Y6. All the coordinate are integer. (X1,Y1) , (X2,Y2), (X3,Y3) forms triangles A ; (X4,Y4) , (X5,Y5), (X6,Y6) forms triangles B.

-10000<=All the coordinate <=10000

## Output

For each test case, output “intersect”, “contain” or “disjoint”.

## Sample Input

2
0 0 0 1 1 0 10 10 9 9 9 10
0 0 1 1 1 0 0 0 1 1 0 1

## Sample Output

disjoint intersect

Problem D Game

## Problem Description

Alice and Bob is playing a game.

Each of them has a number. Alice’s number is A, and Bob’s number is B.

Each turn, one player can do one of the following actions on his own number:

1. Flip: Flip the number. Suppose X = 123456 and after flip, X = 654321

2. Divide. X = X/10. Attention all the numbers are integer. For example X=123456 , after this action X become 12345（but not 12345.6）. 0/0=0.

Alice and Bob moves in turn, Alice moves first. Alice can only modify A, Bob can only modify B. If A=B after any player’s action, then Alice win. Otherwise the game keep going on!

Alice wants to win the game, but Bob will try his best to stop Alice.

Suppose Alice and Bob are clever enough, now Alice wants to know whether she can win the game in limited step or the game will never end.

## Input

First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.

For each test case: Two number A and B. 0<=A,B<=10^100000.

## Output

For each test case, if Alice can win the game, output “Alice”. Otherwise output “Bob”.

4
11111 11
1111112345
54321123 123

Alice
Bob
Alice
Alice

## Hint

For the third sample, Alice flip his number and win the game.

For the last sample, A=B, so Alice win the game immediately even nobody take a move.

1.将这个数反转，eg：123456----->654321

2.将这个数除以10：eg------>123456/10==12345而不是12345.6

eg：123    123000000

AC代码：

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=100000+5;
char a[maxn],b[maxn];
int next[maxn];
int la,lb;
void getNext()
{
int i=0,j=-1;
next[0]=-1;//²»ÒªÍü¼ÇÑ½£¡£¡£¡£¡
while(i<lb)
{
if(j==-1||b[i]==b[j])
{
i++,j++;
next[i]=j;
}
else
j=next[j];
}
}
int KMP()
{
int i=0,j=0;
getNext();
while(i<la)
{
if(j==-1||a[i]==b[j])
i++,j++;
else
j=next[j];
if(j==lb)
return i-j+1;
}
return -1;
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%s%s",a,b);
la=strlen(a);
lb=strlen(b);
/*
if(la<lb)
{
cout<<"Bob"<<endl;
continue;
}
*/
if(KMP()!=-1)
{
cout<<"Alice"<<endl;
}
else
{
for(int i=lb-1;i>=0;i--)
{
if(b[i]=='0')
b[i]='\0';
else
break;
}
lb=strlen(b);
for(int i=0; i<lb/2; i++)
{
swap(b[i],b[lb-1-i]);
}
if(KMP()!=-1)
{
cout<<"Alice"<<endl;
}
else
{
cout<<"Bob"<<endl;
}
}
}
return 0;
}


Problem G YYS

## Problem Description

Yinyangshi is a famous RPG game on mobile phones.

Kim enjoys collecting cards in this game. Suppose there are n kinds of cards. If you want to get a new card, you need to pay W coins to draw a card. Each time you can only draw one card, all the cards appear randomly with same probability 1/n. Kim can get 1 coin each day. Suppose Kim has 0 coin and no cards on day 0. Every W days, Kim can draw a card with W coins. In this problem ,we define W=(n-1)!.

Now Kim wants to know the expected days he can collect all the n kinds of cards.

## Input

The first line an integer T(1 ≤ T ≤ 10). There are T test cases.

The next T lines, each line an integer n. (1≤n≤3000)

## Output

For each n, output the expected days to collect all the n kinds of cards, rounded to one decimal place.

4
1
2
5
9

## Sample Output

1.0
3.0
274.0
1026576.0

1 1/n 1

2 (n-1)/n n(n-1)

. .... ....

n 1/n n

= (1/n + 1/(n-1) + 1/(n-2) +...+ 1/1)*n!

AC代码：

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

BigInteger fac[] = new BigInteger[3000+5];

fac[0] = new BigInteger("1");
for (int i = 1; i <=3000 ; i++) {
fac[i] = fac[i-1].multiply(BigInteger.valueOf(i));
}

Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while(T-->0){
int n = sc.nextInt();
BigInteger ans = new BigInteger("0");
for (int i = 1; i <=n; i++) {
}
System.out.print(ans);
System.out.println(".0");
}

}

}

/**
BigInteger a = BigInteger.valueOf(123);

BigInteger b = new BigInteger("1234656");
*/

Problem K Wand

## Problem Description

N wizards are attending a meeting. Everyone has his own magic wand. N magic wands was put in a line, numbered from 1 to n(Wand_i owned by wizard_i). After the meeting, n wizards will take a wand one by one in the order of 1 to n. A boring wizard decided to reorder the wands. He is wondering how many ways to reorder the wands so that at least k wizards can get his own wand.

For example, n=3. Initially, the wands are w1 w2 w3. After reordering, the wands become w2 w1 w3. So, wizard 1 will take w2, wizard 2 will take w1, wizard 3 will take w3, only wizard 3 get his own wand.

## Input

First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.

For each test case: Two number n and k.

1<=n <=10000.1<=k<=100. k<=n.

## Output

For each test case, output the answer mod 1000000007(10^9 + 7).

2
1 1
3 1

## Sample Output

1
4

①如果他放在了位子k上，然后位子k上的这个数字放在了位子i上，那么对应取k个位子有（i-1）种方法，那么有：

Dp【i】=Dp【i-2】*（i-1）；

②如果他放在了位子k上，然后位子k上的这个数字没有放置在位子i上，同时位子k上的数字变成了一个新的问题，那么有：

Dp【i】=Dp【i-1】*（i-1）；

AC代码：

/**
* 行有余力，则来刷题！
* 博客链接:http://blog.csdn.net/hurmishine
* 个人博客网站:http://wuyunfeng.cn/
*/
//http://blog.csdn.net/mengxiang000000/article/details/75799209
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn = 1e5+5;
const int mod = 1e9+7;
LL dp[maxn];
LL fac[maxn];
LL inv[maxn];
LL qmod(LL a,LL b)
{
LL ans=1;
while(b)
{
if(b&1)
ans = ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}

void Init()
{
fac[0]=1;
for(LL i=1;i<maxn;i++)
{
fac[i]=(fac[i-1]*i)%mod;
}
inv[maxn-1] = qmod(fac[maxn-1],mod-2);
for(LL i=maxn-2;i>=0;i--)
{
inv[i]=(inv[i+1]*(i+1))%mod;
}

dp[0]=1;
dp[1]=0;
for(LL i=2;i<=10000;i++)
{
dp[i]=(i-1)*(dp[i-1]+dp[i-2]);
dp[i]%=mod;
}

}
LL C(int n,int m)
{
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
//freopen("C:\\Users\\17205\\Desktop\\data.txt","r",stdin);
int T,n,k;
Init();
cin>>T;
while(T--)
{
cin>>n>>k;
LL ans=0;
for(int i=k;i<=n;i++)
{
ans+=C(n,i)*dp[n-i]%mod;
ans%=mod;
}
cout<<ans<<endl;
}
return 0;
}


Problem L Tic-Tac-Toe

## Problem Description

Kim likes to play Tic-Tac-Toe.

Given a current state, and now Kim is going to take his next move. Please tell Kim if he can win the game in next 2 moves if both player are clever enough.

Here “next 2 moves” means Kim’s 2 move. (Kim move,opponent move, Kim move, stop).

Game rules:

Tic-tac-toe (also known as noughts and crosses or Xs and Os) is a paper-and-pencil game for two players, X and O, who take turns marking the spaces in a 3×3 grid. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row wins the game.

## Input

First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.

For each test case: Each test case contains three lines, each line three string(“o” or “x” or “.”)(All lower case letters.)

x means here is a x

o means here is a o

. means here is a blank place.

Next line a string (“o” or “x”) means Kim is (“o” or “x”) and he is going to take his next move.

## Output

For each test case:

If Kim can win in 2 steps, output “Kim win!”

Otherwise output “Cannot win!”

3
. . .
. . .
. . .
o
o x o
o . x
x x o
x
o x .
. o .
. . x
o

## Sample Output

Cannot win!
Kim win!
Kim win!

1.Kim要赢，之前棋盘上他的棋子至少要有2颗。

2.有可能Kim再下一步就赢了，所以要枚举没有的空白棋盘，判断Kim是否能赢。

3. 此时，若kim要赢，必须下两步，由于两个人都非常聪明，在kim先下一步之后，对手可能阻止Kim。。。

Kim下了一步之后，再下一步（忽略对手的那一步），如果此时Kim赢的方式大于等于2，则Kim一定赢。因为对手只能阻止一种情况的发生。

AC代码：

#include <iostream>
#include <cstring>
using namespace std;
char a[5][5];
char ch;
int getCnt()
{
int cnt=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(a[i][j]==ch)
cnt++;
}
}
return cnt>=2;
}
bool check()
{
for(int i=0;i<3;i++)
{
if(a[i][0]==ch&&a[i][0]==a[i][1]&&a[i][0]==a[i][2])
return true;
}
for(int j=0;j<3;j++)
{
if(a[0][j]==ch&&a[0][j]==a[1][j]&&a[0][j]==a[2][j])
return true;
}
if(a[0][0]==ch&&a[0][0]==a[1][1]&&a[0][0]==a[2][2])
return true;
if(a[0][2]==ch&&a[0][2]==a[1][1]&&a[0][2]==a[2][0])
return true;
return false;
}
bool two()
{
int cnt=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(a[i][j]=='.')
{
a[i][j]=ch;
if(check())
{
cnt++;
}
a[i][j]='.';
}
}
}
return cnt>1;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int cnt=0;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
cin>>a[i][j];
}
cin>>ch;
if(!getCnt())
{
cout<<"Cannot win!"<<endl;
continue;
}
bool oneFlag=false;
for(int i=0;!oneFlag&&i<3;i++)
{
for(int j=0;!oneFlag&&j<3;j++)
{
if(a[i][j]=='.')
{
a[i][j]=ch;
oneFlag = check();
a[i][j]='.';
}
}
}
if(oneFlag)
{
cout<<"Kim win!"<<endl;
continue;
}
bool flagTwo=false;
for(int i=0;!flagTwo&&i<3;i++)
{
for(int j=0;!flagTwo&&j<3;j++)
{
if(a[i][j]=='.')
{
a[i][j]=ch;
if(two())
{
flagTwo=true;
}
a[i][j]='.';
}
}
}
if(flagTwo)
cout<<"Kim win!"<<endl;
else
cout<<"Cannot win!"<<endl;
}
return 0;
}