题目:人人有钱拿(易)
链接:https://ac.nowcoder.com/acm/contest/53254/A
题目描述:
PhieAsh 常常有一些不切实际的幻想。今天他在洗头时便想到:“如果全世界每个人给我一分钱,我不就是一个大富翁了吗?”PhieAsh 主张人人平等,他希望每个人都能当上大富翁。于是他在梦中安排:让所有人排成一列,按队伍的顺序(从前向后)每个人都从其他所有人拿一分钱。在这个过程前,每个人都至少有 0.01×(n−1)元钱。现在请你编程,帮助 PhieAsh 算出所有人最后的资产。
输入描述:
输出描述:
输入输出:
想法:如我dag所说这个题目就是“收支平衡,所以直接输出就完事””!很简单的,多种表示方法:
①运用STL来写
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int T;
cin >> T;
while (T--)
{
int n;
cin >> n;
std::vector<int> s(n);
for (auto &i : s)
{
cin>>i;
}
for (auto &i : s)
{
cout << i << " ";
}
cout <<endl;
}
return 0;
}
②正常直接输入输出方法
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t,a[200005];
signed main()
{
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
cout<<x<<' ';
}
cout<<endl;
}
return 0;
}
题目: 一剑统治怜悯,一剑送葬绝望
链接:https://ac.nowcoder.com/acm/contest/53254/C?&headNav=acm
题目描述:
xiaoxiao 是一个农批,他最喜欢玩的英雄就是干将莫邪,这英雄有两个技能都是按照一定飞行轨迹扔出一对剑,如图所示:
现在只考虑使用某一个技能(某一对剑)的前提下,为使伤害最大化,xiaoxiao 需要通过走位使得两剑交汇处恰好命中敌方。但现在 xiaoxiao 已经 17 连败被打破防了,他不知道该如何走位,所以他把手机交给你了!
xiaoxiao 操作的干将莫邪现在位于(sx,sy)点,面对在点(tx,ty)挂机的敌方(即地方不能移动)时,xiaoxiao首先会朝着某一个方向移动某距离,随后出剑使得两剑交汇处恰好命中敌方。下图中已经可以出剑命中敌方。
请你回答,xiaoxiao 首先该向哪个方向移动多少距离?
输入描述:
输出描述:
输入输出:
想法:总结方法就是解一个数学题目“ 一开始就有一个坐标轴,那么使用技能的点,可以保持和敌方的y一致,x的坐标相差2*√c/a,然后分别输出 使用技能的点与 原坐标的 横纵坐标差就行了,主要想法就是!’C 移动到(tx,ty)为圆心,sqrt(4c/a)为半径的圆上就行'!
注意:此题不唯一,有很多种!!
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
double sx,sy,tx,ty,m,n;
cin>>sx>>sy>>tx>>ty>>m>>n;
tx -= 2*sqrt(n/m);
sx=tx-sx,sy=ty-sy;
printf("%.8lf %.8lf",sx,sy);
return 0;
}
题目:字符串子序列
链接:https://ac.nowcoder.com/acm/contest/53254/E
题目描述:
给定字符串 s 和 p ,判断 p 是否是 s 的子序列。如果是则输出 "YES",如果不是则输出 "NO"。
对于英文字符,不区分大小写,也就是说对于字符 "A" 和字符 "a" ,我们认为它们是相同的字符。
(∗) 这里的子序列,指的是从一个字符串中不重复地选取一些字符,按照原来的先后顺序组成一个新字符串,这个新字符串就称为原字符串的一个子序列。
例如字符串 "ac" 是字符串 "abc" 的子序列,而 "ca" 不是。
输入描述:
输出描述:
输入输出:
想法:①因为题目描述对于大小写字母是不分的,因此我们就有一个将字母统一的步骤(要么全部小写,要么全部大写),在c++STL中提供了这样一种方法来转换字符串的大小写问题:
C++中有两个函数可进行快速变换大小写,tolower()函数是把字符串都转化为小写字母;touppre()函数是把字符串都转化为大写字s字符串中的字符串转换为大写字母可写为:
transform(s.begin(),s.end(),s.begin(),::tolower);
②第二步就是去找它的子序列了,利用两个数组遍历查找就好,只要根据它的长度就能判断出是否为它的子序列;
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n,i,j=0;
cin>>n;
string s;
cin>>s;
int m;
cin>>m;
string p;
cin>>p;
transform(s.begin(), s.end(), s.begin(), ::tolower);//全部转换成小写字母
transform(p.begin(), p.end(), p.begin(), ::tolower);
for(i=0;i<n;i++)//遍历数组
{
if(s[i]==p[j])//判断是否有相同的字符
{
j++;//用来计数,记载相同的时候,所含p的长度
}
}
if(j==m)//判断是否相等,相等就是子序列,反之则反
{
cout<<"YES";
}
else
{
cout<<"NO";
}
return 0;
}
漂亮学姐说她有更加简答的办法,因为transform那个太长了,她记不住,因此她就只用了tolower这样的函数,下面是她的代码:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
void solve()
{
string a,b;
cin>>n>>a>>m>>b;
ll j=0;
for(int i=0;i<a.size();i++)
{
if(tolower(a[i])==tolower(b[j]))j++;
if(j==m)break;
}
if(j==m)puts("YES");
else puts("NO");
}
signed main()
{
//TT
solve();
return 0;
}
题目: 数字全排列
链接:https://ac.nowcoder.com/acm/contest/53254/F
题目描述:
使用0,1,2,3,4,5,6,7,8,9 共十个数字任意排列组成一个十位数。现在要求你用程序求出满足下列条件的十位数的个数:
1.数字 0 不能排在最高位。
2.所有数字不能重复出现。
3.该十位数是 n 的整数倍
输入描述:
输出描述:
输入输出:
想法:这个题目数据规模其实并不是很大,STL中提供了一种暴力写法用std::next_permutation就行。具体介绍next_permutation,就不介绍了,我贴了一个博主的链接,大家可以看看,或者去哔站学一下,就好哒
下面就是用STL实现的代码了:
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
cin>> n;
long long ans=0,sum;
std::vector<int> s = {1,0,2,3,4,5,6,7,8,9};
do {
sum = 0;
for (auto i : s)
{
sum=sum*10+i;
}
ans+=sum%n==0;
} while (next_permutation(s.begin(),s.end()));
cout << ans;
return 0;
}
当然还有第二种办法,就是写数位dp,大家也可以看看吧
#include <bits/stdc++.h>
using namespace std;
long long sum = 0, s[11] = {0}, book[11] = {0}, n, n1 = 0;
void dfs(int step)
{
if(step == 10)
{
long long x = 0, x1 = 10;
if(s[0] != 0)
{
for(int i = 0; i < 10; i++)
{
x += s[i];
x *=10;
}
x /= 10;
if(x%n == 0)
sum++;
}
}
for(int i = 0; i < 10; i++)
{
if(book[i] == 0)
{
book[i] = 1;
s[step] = i;
dfs(step + 1);
book[i] = 0;
}
}
}
int main()
{
cin >> n;
dfs(0);
cout << sum;
return 0;
}
题目:最大乘积子数组
链接:https://ac.nowcoder.com/acm/contest/53254/I
题目描述:
给定一个长度为 n 的数组,你的任务是找到一个具有最大乘积的非空子数组。
(∗) 这里的子数组,指的是原数组中连续的一段数,比如 [1,2,3] 是数组 [5, 1, 2, 3,0] 的一个子数组,而 [5,2,3] 则不是。
输入描述:
输出描述:
输入输出:
想法:总的来说就是不断去找那个最大值
由于存在负数,那么会导致最大的变最小的,最小的变最大的。因此还需要维护当前最小值imin
保证数组连着 需要统计当前值的最大值和最小值 方便下一位的计算
三个值取最大 (最小值乘以当前数 当前数 最大值乘以当前数)
三个值取最小 ...
如果实在还不理解的话,可以参考力扣解法:https://leetcode.cn/problems/maximum-product-subarray/solution/cheng-ji-zui-da-zi-shu-zu-tu-jie-dpzui-q-jjzv/
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n,i,j;
int a,b,c;
cin>>n;
int s[n];
for(i=0;i<n;i++)
{
cin>>s[i];
}
int zmax,zmin;
zmax=zmin=s[0];
int m=s[0];
for(i=1;i<n;i++)
{
a=s[i];
b=a*zmax;
c=a*zmin;
zmax=max({a,b,c});
zmin=min({a,b,c});
m=max(m,zmax);
}
cout<<m;
return 0;
}
题目:HelloWorld,但是数码管
链接:J-HelloWorld,但是数码管_CCSUTrainingRound 2 (nowcoder.com)
题目描述:
输入描述:
∅ 本题无输入。
输出描述:
思想:这个题目其实读懂题目后是很简单的,本质就是看图找图,然后将图转换为二进制数字,最后再将二进制转换为十进制数字。根据题目可知我们要求的是“helloworld”这个的十进制,总共10个字母,但是我们实际要找的只有7个字母“h” “e” “l” “o” “w” “r” “d”。
因此我们对应两个图分别找出就好:
“h"二进制:1110100 ------------>对应十进制:116
“e"二进制:1111011 ------------>对应十进制:123
“l"二进制:0000110 ------------>对应十进制:6
“o"二进制:1011100 ------------>对应十进制:92
“w"二进制:1101010 ------------>对应十进制:106
“r"二进制:1010000 ------------>对应十进制:80
“d"二进制:1011110 ------------>对应十进制:94
最后就是综合直接输出就行了;
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cout<<"116 123 6 6 92 106 92 80 6 94";
return 0;
}
题目:JZ的巅峰上分计划
链接:https://ac.nowcoder.com/acm/contest/53254/K
题目描述:
JJZ 也是一个农批,她想上巅峰 2100,但是 JJZ 总是先输一局再赢一局。
“输 —— 赢 —— 输 —— 赢 —— 输” 如此循环。
JJZ 是一个稳妥的人类,如果JJZ 的巅峰分大于等于2100 时,JJZ 将不会进行下一局游戏。假设 JJZ 输一局会减 10 分,赢一局加 15 分。JJZ 目前为 k 分,且上一局为输,请你帮帮 JJZ :求出她还需要打多少局,巅峰分才会至少为 2100。
输入描述:
输出描述:
输入输出:
思想:这个题目感觉应该是到签到题,比较简单,就是一个简单的模拟就好;
就是设置一个标记,来标记出赢一局和输一局,这样在循环中,就能直接暴力出来了,没啥好讲的。
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
long long k;
int flag=1;
cin>>k;
int cnt=0;
if(k>=2100)
{
cout<<cnt;
return 0;
}
else
{
while(k<2100)
{
if(flag==1)//赢的时候,flag就是1
{
k+=15;
cnt++;
flag=0;//接下来一句就输掉,所以flag改变为0
}
else
{
k-=10;
cnt++;
flag=1;
}
}
}
cout<<cnt;
return 0;
}
以上就是ccsu训练赛的A、C、E、F、I、J、K的题解了,剩下的题目周末补完题目再写,嘿嘿。
最后就是:
大佬捞捞我,嘿嘿;
不懂的可以评论区一起讨论讨论,嘻嘻!!!