2
4 1 2 3 4
3 10 12 18
10
40
题解:简单的输入输出练习。代码用C++描述,其他语言类似。下同。
#include
using namespace std;
int T,ans,n,temp;
int main(){
cin>>T;
while(T--){
ans=0;
cin>>n;
for(int i=0;i>temp;
ans+=temp;
}
cout<
阿K下课回到宿舍,发现宿舍的人都出去了,但他没有带钥匙,只好在寒风中玩起了2048
输出2的T次方的值
10
1024
题解:由于T很小,32位整形可以存下,所以直接算即可。这里有两个技巧,详细看代码。
#include
#include
using namespace std;
int T;
int main(){
cin>>T;
// cout<
2
1
3
Alice
Bob
题解:就是我们平时小时候玩的游戏。稍微推理一下,就可以得到,当N<=2时,Alice必胜,其他情况都是Bob赢。怎么得到的呢?
先来看看最简单的情况:
O (Alice胜)…………①
OO (Alice胜)…………②
OOO (Bob胜)…………③
OOOO(Bob胜)…………④
对于第四种情况,如果Alice取边缘的两个,就会转换为②的Bob先手态,所以Bob必胜。如果Alice取对角两个,使得剩下两个孤立,实际上就转化为两场①状态的游戏,还是Bob胜。
OOOOO(Bob胜)…………⑤
对于第五种情况。无论Alice怎么取,Bob都可以通过某种策略,使得局势最终都会转化为上述的四种情况之一。读者可以自己尝试下。其他情况同理。所以N>2时Bob必胜。
#include
#include
using namespace std;
int T,n;
int main(){
cin>>T;
for(int i=0;i>n;
if (n<=2)
cout<<"Alice"<
中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。
输入在第一行给出一个正整数N(<100),是每一列的字符数。第二行给出一个长度不超过1000的非空字符串,以回车结束。
按古风格式排版给定的字符串,每列N个字符(除了最后一列可能不足N个)
4
This is a test case
asa T
st ih
e tsi
ce s
题解:这道题主要考察大家的整行输入和二维数组的运用。具体方法的读取整行方法可以百度一下。代码有详细的注释。需要注意的是,剩余的空位要用空格填充。另外控制换行的信息一定要准确。比较绕,希望大家能绕的过来。
#include
#include
#include
using namespace std;
int main() {
char a[1005],b[1005][105];
int la,n,m,i,j,i1;
scanf("%d",&n);
getchar();//把回车符吃掉,否则下一句会出错
gets(a); //读取整行
la=strlen(a); //获得长度
//记录行数
if(la%n==0)
m=la/n;
else
m=la/n+1;
for(i=0;i=la)
b[i][j]=' ';//剩余的用空格填充
else
b[i][j]=a[i1];
i1+=n;
}
}
//循环输出每一个字符
for(i=0;i=0;j--){
printf("%c",b[i][j]);
}
printf("\n");
}
return 0;
}
输入一个质数,现在请你判断是否是质数。如果是的话输出"Yes"否则输出"No"。
一个自然数是质数当且仅当其因子只有1和其本身。
输入有多组数据,第一行为一个整数Q,表示有Q组数据。(1<=Q<=10)
接下来有Q行,每行一个整数n,为待判断的数字。(1<=n<=1000000000)
输出Q行,每行输出Yes或者No,表示是否是质数。注意大小写。
3
5
6
7
Yes
No
Yes
题解:很简单的数学问题,我们很容易就会想到,对于一个数,我们枚举所有可能的约数,然后看看能不能被整除,一旦找到一个,那么就不是质数。于是我们有如下伪代码
FOR i=2 i
IF N mod i = 0
Return False
End IF
End FOR
Return True;
但是这么做是不现实的,如果N很大,比如题目中的10^9,就会超时(计算机1s最多算10^7次加法运算)。因此我们要对我们的算法进行优化。我们很容易想到枚举的时候不用全部枚举。举个例子 11肯定不能被6整除(大于了11的一半)。因此我们只用枚举一半。FOR i=2 i
#include
#include
#include
#include
using namespace std;
bool judge(int x){
for(int i=2;i>Q;
while(Q--){
int n;
cin>>n;
if(judge(n))
cout<<"Yes"<
5
..*..
.*.*.
...**
***..
.....
7
题解:刚接触编程的同学对这题可能无法下手。实际上这道题,只要你对递归调用函数很熟悉的话,应该是很容易的。我们可以模拟洪水泛滥的过程。用一个递归函数,不断的改变一个格子周围四个格子的状态。直到不能被改变为止。递归都很难解释清楚,希望大家看代码能明白。这道题也可以用朴素的做法,但是会有很多的判断条件。
#include
#include
#include
#include
using namespace std;
char maze[1005][1005];
int ans;
//用水淹没
void dfs(int x,int y){
ans+=1;//答案+1
maze[x][y]='1';//1代表该格子已经被水淹没了
//看看周围四个格子是不是平原,是的话就用水淹没它
if(maze[x+1][y]=='.')
dfs(x+1,y);
if(maze[x-1][y]=='.')
dfs(x-1,y);
if(maze[x][y+1]=='.')
dfs(x,y+1);
if(maze[x][y-1]=='.')
dfs(x,y-1);
}
int main() {
int N;
cin>>N;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
cin>>maze[i][j];
ans=0;
dfs(1,1);//用水淹没第一个格子
cout<
斐波纳契数列是这样的数列: f(1) = 1 f(2) = 1 f(3) = 2 f(4) = 3 .... f(n) = f(n-1)+f(n-2) 即从第3项开始,其值等于前两个斐波那契数之和,例如f(3) = f(2)+f(1) = 1+1 = 2 那么现在输入一个数n,判断它是否在斐波那契数列之中
输入一个正整数n(n<=1000000)
如果它在斐波那契数列中则输出 YES 否则输出 NO
5
YES
题解:首先你要知道什么是斐波那契数列,他有一个性质就是,增长得特别快。因此观察题目数据N<=10^6,我们可以直接枚举所有情况就可以了。当然通用的做法是,自己把斐波那契数列求出来,相信大家做作业的时候都做过了。
#include
#include
#include
#include
using namespace std;
int main(){
int n;
cin>>n;
if(n==1||n==2||n==3||n==5||n==8||n==13||n==21||n==34||n==55||n==89||n==144||n==233||n==377||n==610||n==987||n==1597||n==2584||n==4181||n==6765||n==10946||n==17711||n==28657||n==46368||n==75025)
cout<<"YES"<
数学函数也可以递归定义。例如,阶乘函数f(n) = n!可以定义为:
f(1) = 1
f(n) = f(n-1)*n ( n >= 1)
输入一个整数n
输出f(n)的值
5
120
题解:这题非常简单,不多解释了。重点在于数据范围,我们知道,阶乘的增长是爆炸性的,因此我们要用更大的数据类型去存储答案。int不够,我们就用long long int,还不够,那就只能用其他方法了。
#include
using namespace std;
int main(){
long long int n;
cin>>n;
long long int ans=1;
for(long long int i=1;i<=n;i++)
ans*=i;
cout<
姐姐最近沉迷于挖矿,但是由于各种因素的限制,姐姐在同一个地方只能挖一次,而且下一次挖矿的位置只能位于此次所在位置的右方或者下方(姐姐一开始位于地图的左上方),你可以帮姐姐计算一下在一次愉快的挖矿旅程中他最多能挖到多少价值的矿吗?
挖矿区域可以视为正方形,每个格子对应着一次能挖到的矿石的价值,例如
在3*3的正方形中
1 3 3
2 1 3
2 2 1
姐姐所能挖到矿的最大价值为:11(1+3+3+3+1,从(1,1)->(1,2)->(1,3)->(2,3)->(3,3))
第1行:N,N为矩阵的大小。(2 <= N <= 500)
第2 - N + 1行:每行N个数,中间用空格隔开,对应格子中矿石的价值。(1 <= N[i] <= 10000)
输出娴姐能够获得的最大价值。
3
1 3 3
2 1 3
2 2 1
11
题解:这道题咋一看,觉得很简单,对于向右和向下走,我们每次都走值较大的那个,如题目那样。但是稍微想想,就会发现这种策略是错的!比如:
1 3 3
1 1 3
9 2 1
对于一开始,用我们刚刚的策略会往右走,这样子就永远的错过了9了。
这样的话我们可不可以每一次,都判断向下走的和,和向右走的和,看看哪个大走哪个呢?明显是不行的。
1 3 6
1 1 4
9 2 1
用刚刚的策略会往下走,这样子就错过了4了。
还是不行!那么我们就暴力吧!把所有情况都算一遍,找出最大值!复杂度为,2^500。更加不行!那怎么办……再想想,好像暴力其实也可以?我们不必把所有的情况都算一遍,比如
1 3
1 1
我们知道右到下是最优的,下到右是坏的,因此下到右再做任何动作,都不会比右到下优。所以通过这个性质,我们直接把复杂度降到了N^2。对于每一种走法我们只走最优的,那么怎么记录最优的呢?我们直接用一个数组保存最优答案即可。然后我们从左上开始模拟走的情况(即两个for循环),一步一步的把最优答案保存。实际上这是一个叫做动态规划的算法,我们走的每一步,都是从上一步最优的情况得来。详细看代码解释。还不懂的读者,可以自己在草稿纸上,模拟一遍整个数组的填写过程。
#include
using namespace std;
const int MAX_N=550;
int G[MAX_N][MAX_N];//最优值数组
//如G[i][j]=10的意思就是,当贪心姐姐走到第i行第j列时她能得到的最大价值为10
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>G[i][j];//输入
//模拟走的每一种情况
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
G[i][j]=max(G[i-1][j]+G[i][j],G[i][j-1]+G[i][j]);//这一步是从上走下来优呢,还是从左走过来优呢?
}
}
//这个就是答案
cout<
小李专业割绳子三十年,如果你给他N条绳子,长度分别为Li,并告诉他要割成K条长度相同的绳子,那么小李肯定能最优的割成K条绳子,并保证它们肯定是最长的!
输入的第一行为一个正整数T(T <= 10),表示有T组数据。
接下来每组数据有三行。
第一行为一个正整数N(1≤N≤10000)。
第二行为一个正整数K(1≤K≤10000)。
第三行为 Li,中间用空格隔开 (1≤Li≤100000)。
对于每组数据,输出最长的长度(答案保留到小数点后两位)
2
4
11
8.02 7.43 4.57 5.39
6
10
3 4 5 6 7 5
2.00
2.50
题解:这题需要一定的算法基础,才能做出,因此在这里不做详细的解释。做这题前首先要理解二分搜索算法。对于有序的数组,我们可以通过二分,在很快的时间内找到你要找的数。比如 1 2 3 4 5 6 7,你要找6,我们先从中间开始,中间为4,6比4大,因此6一定在4的右边,所以我们就可以递归查找,问题变为,在 5 6 7 中找6 。然后我们就找到了。如果找的是1,我们就变为在1 2 3 中找1,然后再在1 中找 1。相信读者都能明白这个道理。那么回到题目,我们要找到一个最长的长度,使得剪出来刚好有K段。那么我们把答案想象成一个有序的序列 1 2 3 4 5 6 7 8 9 我们先假设,5就是答案,那么我们就看看题目给的绳子,把他们都尽可能的切成5,看看能不能凑成K段。这个时候有两种情况,一种是凑成了>=K段,一种是
#include
#include
#include
#include
using namespace std;
#define MAX 10000
#define INF 10000000
bool panduan(double x,int n,int k,double Li[]){
int num =0;
for (int i=0;i=k;
}
int main(){
int n;
cin>>n;
int a[n],b[n];
double num[n];//记录答案
for(int i=0;i>a[i]>>b[i];
double Li[MAX];
for(int j=0;j>Li[j];
double lb=0,ub=INF;//把答案的下界设为0,上界设为一个足够大的数
//100次二分足以!
for(int j=0;j<100;j++){
double mid =(lb+ub)/2;
if(panduan(mid,a[i],b[i],Li))//如果能切成K段,
lb=mid;//尝试把答案放大
else
ub=mid;//尝试把答案缩小
}
num[i]=floor(int(ub*100))/100;//保留两位小数
}
for(int i=0;i
表达式N!称为N的阶乘,是指前N个正整数的乘积,其中N是正数。现在给出N,请计算N的阶乘最右一位非0数字。
输入的第一行为一个正整数T(T <= 1000),表示有T组数据。 接下来每组数据有一行,为一个正整数N(1≤N≤10000)
对于每组数据,输出最右一位非0数字。
4
1
2
5
9999
1
2
2
8
题解:这道题由于数据范围较小,因此有简单的做法。我们都知道123000乘任何数,后面的三个0都不会变,变得只是前面的123,有时候还会生成多几个0。因此我们每算一次就把后面的所有0都截掉。最后剩下的取第一位就行了。这里有一个问题,就是溢出问题。阶乘是一个很大的数,long long int也无法存下,但是我们只关心后面的数字,前面的因数字是什么我不关心,此我们要剪掉前面无用的数字。具体剪掉多少呢?数据范围较小,只要剪足够少就可以了。用取模运算即可剪,具体看代码。当然这道题有更通用的做法,我们都知道2*5等于10,所以因子2和5会产生0,因此我们要剔除所有的2,5因子,具体不解释了。
#include
using namespace std;
int main(){
int T;
long long int sum,N;
cin>>T;
while(T--){
cin>>N;
sum=1;
for(int i=1;i<=N;i++){
sum=sum*i;
while(sum%10==0){
sum=sum/10;
}
sum=sum%1000000;
}
sum=sum%10;
cout<
谢谢阅读!