我是个没有感情的WA题机器人
(一)课堂
A - 小兔的棋盘 HDU - 2067
小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!
Input
每次输入一个数n(1<=n<=35),当n等于-1时结束输入。
Output
对于每个输入数据输出路径数,具体格式看Sample。
Sample Input
1
3
12
-1
Sample Output
1 1 2
2 3 10
3 12 416024
AC代码
#include <bits/stdc++.h>
using namespace std;
int main(){
long long cat[40];
memset(cat,0,sizeof(cat));
cat[0] = 1; cat[1] = 1;
for(int i = 2;i <= 35;i++){
for(int j = 0;j <= i-1;j++){
cat[i] += cat[j]*cat[i-j-1];
}
}
int n;
int k = 1;
while(cin >> n){
if(n == -1) break;
cout << k++ << " " << n << " " << cat[n]*2ll << endl;
}
return 0;
}
(二)有趣的题目
A - Super A^B mod C FZU - 1759
之前几道大数题都java偷过去了嘻嘻
题目描述
Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000000000,1<=B<=10^1000000).
Input
There are multiply testcases. Each testcase, there is one line contains three integers A, B and C, separated by a single space.
Output
For each testcase, output an integer, denotes the result of A^B mod C.
Sample Input
3 2 4
2 10 1000
Sample Output
1
24
理解
谁能相信,这题我wa了8发!!!
然后紫妈说这只是一道欧拉降幂,很简单的(我并不觉得)
AC代码
#include<iostream>
#include<cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e7 + 5;
ll a,c;
char s[N];
ll Euler(ll a){
ll t = a;
for(ll i = 2;i*i <= a;i++){
if(a % i == 0){
t = t/i*(i-1);
while(a % i == 0){
a /= i;
}
}
}
if(a!=1) t = t / a *(a-1);
return t;
}
ll p(ll a,ll b,ll mod){
ll sum = 1;
a %= mod;
while(b){
if(b & 1) sum = sum * a % mod;
a = a * a % mod;
b >>= 1;
}
return sum % mod;
}
int main(){
while(~scanf("%lld%s%lld",&a,s,&c)){
ll ans = 0;
ll m = Euler(c);
int len = strlen(s);
for(ll i = 0;i < len;i++){
ans = (ans * 10 + s[i] - '0') % m;
ans += m;
}
printf("%lld\n",p(a,ans,c));
}
return 0;
}
B - Grids HDU - 4828
度度熊最近很喜欢玩游戏。这一天他在纸上画了一个2行N列的长方形格子。他想把1到2N这些数依次放进去,但是为了使格子看起来优美,他想找到使每行每列都递增的方案。不过画了很久,他发现方案数实在是太多了。度度熊想知道,有多少种放数字的方法能满足上面的条件?
Input
第一行为数据组数T(1<=T<=100000)。
然后T行,每行为一个数N(1<=N<=1000000)表示长方形的大小。
Output
对于每组数据,输出符合题意的方案数。由于数字可能非常大,你只需要把最后的结果对1000000007取模即可。
Sample Input
2
1
3
Sample Output
Case #1:
1
Case #2:
5
提示
对于第二组样例,共5种方案,具体方案为:
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll m = 1000000007;
const int maxn = 1e6 + 5;
ll c[maxn];
ll ex_g(ll a,ll b,ll &x,ll &y){
if(b == 0){
x = 1;
y = 0;
return a;
}
ll k = ex_g(b,a%b,x,y);
ll t = x;x = y;y = t-a/b*y;
return k;
}
int main(){
ll x,y;
c[0] = 1;c[1] = 1;
for(int i = 2;i < maxn;i++){
x = c[i-1];
c[i] = (x*(4*i-2)) % m;
ex_g(i+1,m,x,y);
x = (x+m) % m;
c[i] = (c[i]*x) % m;
}
int t;
scanf("%d",&t);
for(int e = 1;e <= t;e++){
int n;
scanf("%d",&n);
printf("Case #%d:\n%lld\n",e,c[n]);
}
return 0;
}
C - Fibonacci again and again HDU - 1848
任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:
F(1)=1;
F(2)=2;
F(n)=F(n-1)+F(n-2)(n>=3);
所以,1,2,3,5,8,13……就是菲波那契数列。
在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题。
今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下:
1、 这是一个二人游戏;
2、 一共有3堆石子,数量分别是m, n, p个;
3、 两人轮流走;
4、 每走一步可以选择任意一堆石子,然后取走f个;
5、 f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
6、 最先取光所有石子的人为胜者;
假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢。
Input
 输入数据包含多个测试用例,每个测试用例占一行,包含3个整数m,n,p(1<=m,n,p<=1000)。
m=n=p=0则表示输入结束。
Output
如果先手的人能赢,请输出“Fibo”,否则请输出“Nacci”,每个实例的输出占一行。
Sample Input
1 1 1
1 4 1
0 0 0
Sample Output
Fibo
Nacci
理解
血与泪的历史wa了8发告诉我们判断的时候一定要注意优先级!!!!
果然莽交的题都是死于自己菜,嘤嘤嘤
AC代码
#include <bits/stdc++.h>
using namespace std;
int fib[21]={0};
int sg[1010];
void createSG(int n) {
memset(sg,0,sizeof(sg));
for (int i = 1;i <= n;i++){
bool v[n]={0}; //自然数没有出现过
for(int j = 0;fib[j] <= i;j++){
v[sg[i-fib[j]]] = true;
}
for(int j = 0;j <= n;j++){
if(!v[j]){
sg[i]=j;
break;
}
}
}
}
int main(){
fib[0]=1; fib[1]=1;
for(int i=2;i<=20;i++)
fib[i] = fib[i-1] + fib[i-2];
int n,m,p;
createSG(1000);
while(cin >> n >> m >> p && n && m && p){
if(sg[m]^sg[n]^sg[p]) cout << "Fibo" << endl;
else cout << "Nacci" << endl;
}
return 0;
}
D - Stone Game, Why are you always there? HDU - 2999
“Alice and Bob are playing stone game…”
“Err… Feel bored about the stone game? Don’t be so, because stone game changes all the time!”
“What the hell are they thinking for?”
“You know, whenever Alice is trying to make fun of Bob, she asked him to play stone game with him.”
“Poor Bob… What’s the rule today?”
“It seems Alice only allows some fixed numbers of continuous stones can be taken each time. And they begin with one string of stones.”
“A string? Formed as a circle or a line?”
“A line.”
“Well, I think I may help Bob with that.”
“How?”
“I may tell him to skip this round if he has no chance to win.”
“Good idea maybe, I mean, Alice always let Bob play first, because she think herself is smart enough to beat Bob no matter how.”
“Yes, she’s actually right about herself. Let me see if Bob has a chance to win…”
Input
There are multiple test cases, for each test case:
The first line has a positive integer N (1<=N<=100).
The second line contains N positive integers, a1, a2 … an, separated by spaces, which indicate the fixed numbers Alice gives.
The third line, a positive integer M. (M<=1000)
Following M lines, one positive integer K (K<=1000) each line. K means in this round, the length of the stone string.
Output
For each K, output “1” if Bob has a chance to win, output “2” if Bob has no chance, or “0” if it’s undeterminable.
Sample Input
3
1 5 1
1
1
Sample Output
1
AC代码
#include <bits/stdc++.h>
using namespace std;
int ans;
const int N = 1000 + 5;
int sg[N];
int a[105];
//求每个结点的sg值
int createSG(int n){
if(sg[n] != -1) return sg[n];
bool s[N] = {0};
for(int i = 0;i < ans;i++){
if(n < a[i]) break;
for(int j = 0;j <= n - a[i];j++){
if(sg[j] == -1) sg[j] = createSG(j);
if(sg[n-j-a[i]] == -1) sg[n-j-a[i]] = createSG(n-j-a[i]);
s[sg[j]^sg[n-j-a[i]]] = 1;
}
}
for(int i = 0;;i++){
if(!s[i]){ //如果找到第一个没出现过的自然数就是所求的
return i;
}
}
}
int main(){
int n,m;
while(cin >> n){
for(int i = 0;i < n;i++) scanf("%d",&a[i]);
sort(a,a+n);
ans = 1;
for(int i = 1;i < n;i++){ //去重
if(a[i] != a[ans-1]){
a[ans++] = a[i];
}
}
cin >> m;
memset(sg,-1,sizeof(sg));
while(m--){
int b;
scanf("%d",&b);
if(sg[b] == -1) sg[b] = createSG(b);
if(sg[b]) puts("1");
else puts("2");
}
}
return 0;
}
E - Text Reverse HDU - 1062
题目描述
Ignatius likes to write words in reverse way. Given a single line of text which is written by Ignatius, you should reverse all the words and then output them.
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. T test cases follow.
Each test case contains a single line with several words. There will be at most 1000 characters in a line.
Output
For each test case, you should output the text which is processed.
Sample Input
3
olleh !dlrow
m’I morf .udh
I ekil .mca
Sample Output
hello world!
I’m from hdu.
I like acm.
理解
看着十分眼熟的一道题。。。本来没有摘录的必要,but我输出超限wa了四次并且没有找到错(是直接string前后交换来的)
然后果然是自己太菜有必要记录一下自己的菜鸡时刻
AC代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
getchar();
while(n--){
char s[1005];
gets(s);
int l = strlen(s);
for(int i = 0;i < l;i++){
int k = i;
while(s[i] != ' ' && s[i] != '\0'){
i++;
}
int j = i;
for(int x = i-1;x >= k;x--) cout << s[x];
if(s[j] == ' ') printf(" ");
}
cout << endl;
}
return 0;
}
F - Four Operations HDU - 5938
Little Ruins is a studious boy, recently he learned the four operations!
Now he want to use four operations to generate a number, he takes a string which only contains digits ‘1’ - ‘9’, and split it into 5 intervals and add the four operations ‘+’, ‘-’, ‘*’ and ‘/’ in order, then calculate the result(/ used as integer division).
Now please help him to get the largest result.
Input
First line contains an integer T, which indicates the number of test cases.
Every test contains one line with a string only contains digits ‘1’- ‘9’.
Limits
1≤T≤105
5≤length of string≤20
Output
For every test case, you should output ‘Case #x: y’, where x indicates the case number and counts from 1 and y is the result.
Sample Input
1
12345
Sample Output
Case #1: 1
理解
起先想简单了这个题目。给一串数字,然后分割成五个数,中间按序添加+-*/,最后输出获取最大的结果数
-c*d/e一定是一个负数,那么我们将其值尽可能的缩小,并且让a+b尽可能的大
枚举一个位子i,来界限a+b和-c*d/e,位子i之前的数字使得a+b最大,位子i后边按照上述过程计算出来,然后将两个数相减,得到一个可行解,然后在枚举位子i的过程中,保持一个最大值即可。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int cas;
cin >> cas;
for(int x = 1;x <= cas;x++){
string s;
cin >> s;
ll a,b,c,d,e;
ll ans = -0x3f3f3f3f;
int l = s.size();
for(int i = 1;i < l-3;i++){
a = s[0] -'0';
b = 0;
for(int j = 1;j <= i;j++)
b = b * 10 + s[j] - '0';
ll maxn = a+b;
a = 0;
b = s[i] - '0';
for(int j = 0;j <= i-1;j++)
a = a * 10 + s[j] - '0';
maxn = max(maxn,a+b);
c = s[i+1]-'0';
d = s[i+2]-'0';
e = 0;
for(int j = i+3;j < l;j++) e = e * 10 + s[j] - '0';
// cout << a << " " << b << " " << c << " " << d << " " << e << endl;
ans = max(maxn-c*d/e,ans);
}
printf("Case #%d: %lld\n",x,ans);
}
return 0;
}
G - Substrings HDU - 1238
You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
Input
The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
Output
There should be one line per test case containing the length of the largest string found.
Sample Input
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
Sample Output
2
2
AC代码
#include <bits/stdc++.h>
using namespace std;
string s[110],ss;
int main(){
int t;
cin >> t;
while(t--){
int n,maxn = 0;
cin >> n;
for(int i = 1;i <= n;i++){
cin >> s[i];
if(s[i].length() > maxn){
maxn = s[i].length();
ss = s[i];
}
}
int cnt = 0;
for(int i = 0;i < maxn;i++){
for(int j = 1;j <= maxn - i;j++){
int f = 0;
string c1 = ss.substr(i,j),c2;
c2 = c1;
reverse(c2.begin(),c2.end());
for(int k = 1;k <= n;k++){
if(s[k] != ss){
int idx = s[k].find(c1);
if(idx == -1){
f = 1;
break;
}
}
}
if(f == 0 && j > cnt){
cnt = j;
}
f = 0;
for(int k = 1;k <= n;k++){
if(s[k] != ss){
int idx = s[k].find(c2);
if(idx == -1){
f = 1;
break;
}
}
}
if(f == 0 && j > cnt){
cnt = j;
}
}
}
cout << cnt << endl;
}
return 0;
}
(三)我的感想(die)
关于这周的日常练习
集训的最后一周, 看起来题目似乎轻松了一些(并不),都轻松了好多,(好像也没有),依旧是发现自己是菜鸡写不来题目的每一天,但不知道为啥虽然学了hash依旧是暴力法过题,果然暴力法天下第一!!!既然是开学在即那么就划划水?不存在的。或许开学算是一个弥补以前漏洞的好机会?打算怼着dfs以及二叉树再学一些,毕竟都会了才有勇气以后上课划水(ak后划水),网络赛也算是对自己阶段性的测验吧,毕竟一个暑假下来,广学了不少,但到实际运用起来还是有点吃力的,想着以后可以在5101拥有一席之地(现在是5508)也算是对于我这样一个有拖延症且不愿意好好读书的人一个督促自己学习的平台和空间,未来要和大家一起努力鸭(努力划水鸭)
关于icpc的网络赛
银川赛依旧很迷,传说中的物理防ak系统,知乎上的段子也是一套一套的,总而言之,交了一道dp,后来看是wa了的,还有一题数学题写了没交,思路理完很清晰,小错误太多了导致浪费时间,在三角形算面积上产生了分歧,没有用1/2absin西塔而是用的1/2底*高,然后由于斜率不存在的情况分类太麻烦,就来不及改完。。。怪我