A.计算器 | |||||
|
|||||
Description | |||||
给出一个形如“A+B”的式子,要求计算结果 | |||||
Input | |||||
多组数据,读入到文件结尾 对于每一组数据,都是一行字符串 |
|||||
Output | |||||
对于每组测试数据,输出对应的结果 | |||||
Sample Input | |||||
123+456 2+4 |
|||||
Sample Output | |||||
579 6 |
|||||
Hint | |||||
保证 A 和 B 都在 int 范围内且都是整数 |
貌似考察分离字符串数字的能力...emmmm一个sscanf就够了,不过因为A,B是int型,A+B就可能超过哦,一个小坑点
#include
using namespace std;
#define ll long long
const int maxn=1e5+5;
int main()
{
char a[maxn];
ll x,y;
while(cin>>a)
{
int flag=0;
for(int i=0;;i++)
{
if(a[i]=='+')
{
flag=i;
break;
}
}
sscanf(a,"%lld%lld",&x,&y);
printf("%lld\n",x+y);
}
}
B.摆书 | |||||
|
|||||
Description | |||||
Quasrain 和 FZ 是好朋友。某天老师交给他们两组相同的书,每组书都是 n 本且不重复。他们需要把这两组书排列到一行 n 个书架上,每个书架上放两本书,且同一个人不能在同一个书架上放两本书。现在他们想知道,每个书架上的两本书都不一样的方案数。这n个书架互相等价,不区分顺序 | |||||
Input | |||||
多组数据,读入到文件结尾。 对于每一组数据,包含一个数 n,意义如题面所示 |
|||||
Output | |||||
对于每组数据,输出方案数,对 998244353 取模后的值 | |||||
Sample Input | |||||
2 3 4 |
|||||
Sample Output | |||||
1 2 9 |
|||||
Hint | |||||
2<=N<=10^5 输入数据不超过 100 行 对于第二组样例:摆放方式有 甲取{1,2,3},乙取{2,3,1} 甲取{1,2,3},乙取{3,1,2} 甲取{1,2,3},乙取{2,3,1}的方案与甲取{2,1,3},乙取{3,2,1}的方案等价 |
错排典型例题...
公式f(n)=(n-1)*(f(n-1)+f(n-2))
不了解错排的戳这里https://blog.csdn.net/xiaohuan1991/article/details/6416047
#include
using namespace std;
#define ll long long
#define Mod 998244353
const int maxn=1e5+5;
long long a[maxn];
void f()
{
a[2]=1;
a[3]=2;
a[4]=9;
for(int i=5;i
C.挖坑 | |||||
|
|||||
Description | |||||
Quasrain 和 FZ 是好朋友。Quasrain 善于挖坑而 FZ 善于填坑。 这个游戏一共会持续 2N 天。在每一天都会有人挖坑或者填坑,并在本子上记录下“A”表示这天挖了坑,“B”表示填了坑。填坑必须填一个现存的还没有被填过的坑。 作为素质优秀的熊孩子,他们保证在最后一天结束的时候一定会恰好填平所有坑。 问本子上可能有多少种不同的 AB 序列 |
|||||
Input | |||||
第一行一个数 T 表示数据组数(T<=100000) 之后 T 行每行一个数 N,意义如题面所示(1<=N<=1000)
|
|||||
Output | |||||
对于每组数据输出方案数,对 998244353 取模 | |||||
Sample Input | |||||
3 1 2 3 |
|||||
Sample Output | |||||
1 2 5 |
|||||
Hint | |||||
对于第三组样例: 可能的 AB 序列分别为:{AAABBB},{AABABB},{AABBAB},{ABAABB},{ABABAB} |
任意前缀中A的个数不少于B的个数,妥妥的卡特兰数,我用的是c(n)=c(n-1)*(4*n-2)/(n+!) 由于卡特兰数太大惹,我就用了java的BigInteger,然鹅java没有双倍实现悲催的TLE,于是就打了个表QAQ,
卡特兰数讲解https://blog.csdn.net/wu_tongtong/article/details/78161211
java的卡特兰数打表
import java.math.BigInteger;
import java.util.Scanner;
public class hdu1042 {
static BigInteger a[] = new BigInteger[10000+5];
static BigInteger b = new BigInteger("998244353");
static Scanner cin = new Scanner(System.in);
public static void f() {
a[1] = new BigInteger("1");
for(int i=2;i<=1005;i++) {
a[i]=(a[i-1].multiply(new BigInteger(String.valueOf(4*i-2))).divide(new BigInteger(String.valueOf(i+1))));
}
}
public static void main(String[] args) {
// int t=cin.nextInt();
// int tt=0;
f();
for(int i=1;i<=1005;i++)
{
System.out.println(a[i].remainder(b));
System.out.println(",");
}
// while(tt
#include
#include
#include
#include
using namespace std;
#define ll long long
int c[1000+5]={表.....};//为了不污染视线,表就不上了
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
printf("%d\n",c[n-1]);
}
return 0;
}
1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,2674440,9694845,35357670,129644790,477638700,769018837,574654302,508402548(表的前几位)
E.复读机 | |||||
|
|||||
Description | |||||
人类的本质是复读机,当然也包括 Quasrain 和 FZ “+1”按钮当且仅当在至少两次同样的字符串之后可以被点击。 所有可以点击“+1”按钮的时候 FZ 都会点击,但 FZ 不喜欢复读自己。 比如出现连续三个字符串”aaa”,”aaa”,”aaa”时,他只会在第二次出现”aaa”时点击一次”+1”按钮 现在给出 n 个字符串表示当天的聊天记录,出于研究目的,Quasrain 想要知道 FZ 一天里需要点击多少次”+1”按钮。 |
|||||
Input | |||||
第一行一个正整数 T,表示数据组数(T<=5) 对于每组数据:第一行一个正整数 n 表示今日的聊天记录条数(n<=1000) 接下来 n 行每行一个字符串,保证字符串长度<=1000,且仅会出现大小写字母和数字 |
|||||
Output | |||||
对于每组测试数据,输出一行一个整数表示答案 | |||||
Sample Input | |||||
1 6 111 111 22 111 111 111 |
|||||
Sample Output | |||||
2 | |||||
Hint | |||||
点击分别在第 2 行和第 5 行 |
E.复读机 | |||||
|
|||||
Description | |||||
人类的本质是复读机,当然也包括 Quasrain 和 FZ “+1”按钮当且仅当在至少两次同样的字符串之后可以被点击。 所有可以点击“+1”按钮的时候 FZ 都会点击,但 FZ 不喜欢复读自己。 比如出现连续三个字符串”aaa”,”aaa”,”aaa”时,他只会在第二次出现”aaa”时点击一次”+1”按钮 现在给出 n 个字符串表示当天的聊天记录,出于研究目的,Quasrain 想要知道 FZ 一天里需要点击多少次”+1”按钮。 |
|||||
Input | |||||
第一行一个正整数 T,表示数据组数(T<=5) 对于每组数据:第一行一个正整数 n 表示今日的聊天记录条数(n<=1000) 接下来 n 行每行一个字符串,保证字符串长度<=1000,且仅会出现大小写字母和数字 |
|||||
Output | |||||
对于每组测试数据,输出一行一个整数表示答案 | |||||
Sample Input | |||||
1 6 111 111 22 111 111 111 |
|||||
Sample Output | |||||
2 | |||||
Hint | |||||
点击分别在第 2 行和第 5 行 |
这个题,貌似题意不是很明确,所以造成了理解坑点...我开始想的是A说的话他复读了,然后B也复读了,他也可以复读B说的话呢...结果交了一发WA,然后才知道的一个复读区间段只能复读一次...
K.选数 II | |||||
|
|||||
Description | |||||
有一行 n 个数,其中所有数都恰好出现了两次,除了两个特殊的数只出现了一次。现在 Quasrain 想知道这两个特殊的数分别是多少 | |||||
Input | |||||
多组数据。 第一行一个整数 T 表示数据组数(T<=5) 对于每组数据,第一行一个整数 n,意义如题面所示(保证 n 为偶数,n<=100000) 接下来一行 n 个正整数 Ai。(0<=Ai<2^31-1) |
|||||
Output | |||||
对于每组数据,输出一行两个正整数,表示两个特殊的数,按小的在前大的在后的顺序输出 | |||||
Sample Input | |||||
2 4 2 2 3 4 6 1 2 3 2 3 5 |
|||||
Sample Output | |||||
3 4 1 5 |
|||||
Hint | |||||
请使用高效的读入方式 |
其实这个题是一个题的拓展,原题是有一行 n 个数,其中所有数都恰好出现了两次,除了一个特殊的数只出现了一次。求这个特殊的数是多少
由于a^a=0,也就a^b^a=b,所以,全部的数异或起来,所得的结果就是这个特殊的数。
这里是两个特殊的数,其实整体思路也是这样。
把全部的数异或起来,根据上面知道,结果是两个特殊的数的异或sum。然后算出sum的二进制第一个1的位置flag,再将所有数根据二进制flag位置是否为1分成两组b1[],b2[] ,将b1组异或得到ans1,将b2组异或得到ans2
#include
using namespace std;
const int maxn=1e5+5;
int a[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int sum=0;
for(int i=0;i>flag)&1))
flag++;//sum的二进制第一个1的位置flag
flag=1<