1.17 UPC寒假个人训练第8场
问题 A: 打印图形VI
题目描述
由键盘输入任意一个自然数N,输出如右图规律的图形。如:N=5时的图形为:
输入
只有一个整数N,为图形的行数(其中2≤N≤26)。
输出
输出指定格式的图形。
样例输入
5
样例输出
A
BAB
CBABC
DCBABCD
EDCBABCDE (//怎么这复制过来空格没了,算了反正也没人会看这种水题)
# include<bits/stdc++.h>
using namespace std;
int n;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
char c='A'+i-1,d='A';
for(int j=1;j<=n-i;j++)
printf(" ");
for(int k=1;k<=2*i-1;k++){
if(c<'A')
printf("%c",++d);
else printf("%c",c--);
}
printf("\n");
}
}
问题 B: 数列计算V
题目描述
数学老师在黑板上写出了一个分数序列:2/3,3/5,5/7,8/9,12/11,17/13…,让同学们来进行观察。小明同学首先看出了分子的规律,小红同学也看出了分母的规律。现在指定项数为任意的N项,请同学们共同比试一下,看谁能把前N项的这组数据算得又快又好?同时将这组数据按从小到大的顺序进行排列输出?
输入
只有一行,包含1个整数N(其中2≤N≤15)为这个分数序列的项数。
输出
共有2*N行:
前N行每行一个数据为这个分数序列各项的数值;
后N行每行一个数据为将这组数据按从小到大的顺序进行排列输出。
样例输入
3
样例输出
0.6666667
0.6000000
0.7142857
0.6000000
0.6666667
0.7142857
看了一眼2-15??这打表不是2min解决,(打表yyds
# include<bits/stdc++.h>
using namespace std;
int x,m,n,y;
double a[20];
int main(){
cin>>n;
a[1]=2.0/3;
a[2]=3.0/5;
a[3]=5.0/7;
a[4]=8.0/9;
a[5]=12.0/11;
a[6]=17.0/13;
a[7]=23.0/15;
a[8]=30.0/17;
a[9]=38.0/19;
a[10]=47.0/21;
a[11]=57.0/23;
a[12]=68.0/25;
a[13]=80.0/27;
a[14]=93.0/29;
a[15]=107.0/31;
for(int i=1;i<=n;i++)
printf("%.7lf\n",a[i]);
sort(a,a+15);
for(int i=1;i<=n;i++)
printf("%.7lf\n",a[i]);
return 0;
}
问题 C: 报数
题目描述
参加团体操的同学共有N名,他们面对教练站成一排,自左至右按1,2,3,4,……依次报数,教练让每个同学记住自己报的数并做以下动作:先让报数是3的倍数的同学向后转,接着让报数是5的倍数的同学向后转,最后让报数是7的倍数的同学向后转(注意:凡是向后转的同学都不能再向前转),问:现在仍然面向教练的是哪些同学?共有多少人?
输入
共有一行,包含1个整数N(其中1<N≤100)为参加团体操的的同学数量。
输出
共有若干行:
前若干行每行一个整数为仍然面向教练的同学;
最后一行包含1个整数为面向教练的同学人数。
样例输入
20
样例输出
1
2
4
8
11
13
16
17
19
9
# include<bits/stdc++.h>
using namespace std;
int n,ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
if(i%3==0||i%5==0||i%7==0) continue;
cout<<i<<endl;
ans++;
}
cout<<ans<<endl;
return 0;
}
问题 D: 求素数III
题目描述
在四位自然数中有这样一些特点的数:
(1)它们是素数;
(2)它们的个位数字与十位数字之和恰好等于百位数字与千位数字之和。
求出任意自然数M ~N之间所有满足上述条件的素数,并统计这样的素数的个数。
输入
只有一行,包含两个用空格隔开的任意自然数M和N(其中1000≤M≤9999, 1000≤N≤9999)。
输出
共有若干行:
前若干行每行一个整数是任意自然数M~N之间所有满足条件的素数;
最后一行是统计这些素数的个数。
样例输入
2000 3000
样例输出
2011
2213
2341
2543
2617
2671
2819
2837
8
提示
如果没有符合条件的,只需要输出一个整数0
这题对完看了一眼发现不对劲,我都没考虑输出0……居然都对了,我是不是应该再完善一下,算了对都对了,要完善你去完善。
# include<bits/stdc++.h>
using namespace std;
int x,m,n,y,ans;
int a[10000];
void fun(){
for(int i=2;i<=sqrt(10000);i++)
if(a[i]==0) {
for(int j=i*i;j<10000;j+=i)
a[j]=1;
}
}
int main(){
scanf("%d%d",&n,&m);
fun();
for(int i=n;i<=m;i++){
if(a[i]==0) {
int b=i/1000;
int c=i/100%10;
int d=i/10%10;
int e=i%10;
if(d+e==b+c)
cout<<i<<endl,ans++;
}
}
cout<<ans<<endl;
return 0;
}
问题 E: 求子串
题目描述
同学们都知道,字符串的概念指的是:用引号“ ”括起来的一串有限序列的字符。而子字符串就是字符串内的字符序列。例如,字符串 “abc” 具有如下6个子字符串:“a”、“ab”、“abc”(本身也计算在内)、“b”、“bc”、“c”。
现在任意给出一个字符串,请同学们编一个程序输出每个不同的子串,并统计不同的子串的个数。
输入
只有一行,包含1个任意的字符串(其长度L≥5)
输出
共有若干行:
前若干行每行一个字符串为不同的子串;
最后一行为统计不同的子串的个数。
样例输入
abcde
样例输出
a
ab
abc
abcd
abcde
b
bc
bcd
bcde
c
cd
cde
d
de
e
15
这题一开始往指数型那题搜索考虑去了,因为实在太像了,结果没做出来。然后补题问了某大哥发现别人写的真简单……我傻了
# include<iostream>
# include<string>
using namespace std;
string s;
long long ans;
int main(){
cin>>s;
ans=s.length();
for(int i=0;i<s.size();i++){
for(int j=i,l=1;j<s.size();j++,l++)
cout<<s.substr(i,l)<<"\n"; //别问为啥写的这么奇怪,写endl超时换成\n 86ms,我也很诧异
//不信自己去试试。。
}
printf("%lld\n",ans*(ans+1)/2);
return 0;
}
问题 F: 计算图形的边长
题目描述
下图是由四个大小一样的长方形和一个小的正方形拼成的一个面积为M平方厘米的大正方形。其中小正方形的面积是N平方厘米,试求出拼成的长方形的短边长度是几厘米?
输入
只有一行,包含两个用空格隔开的数值M和N,分别代表大正方形和小正方形的面积(其中0<M<200,0<N<100且M>N)。
输出
共有一行,包含一个数据为长方形的短边长度。
要求:将长方形短边长度的数值四舍五入保留二位小数;
样例输入
150 80
样例输出
1.65
输入一开始没考虑double,还错了两次……
# include<bits/stdc++.h>
using namespace std;
double x,m,n,y,ans;
int a[10000];
double l;
int main(){
cin>>n>>m;
l=sqrt(n)-sqrt(m);
l=l/2;
printf("%.2lf",l+0.0005);
return 0;
}
问题 G: 出租车费
题目描述
某城市的出租车收费标准如下:
假设打车路程为x公里:
(1)起步价9.0元(不超过3公里,即:0<x<=3;);
(2)3公里后:白天1.5元/公里;夜间1.75元/公里;
(3)6公里后:白天2.25元/公里;夜间2.5元/公里。
如:白天打车路程x=10公里,费用计算方法如下:
前3公里起步价9.0元;3公里到6公里费用31.5;6公里后的费用42.25,共计22.5元。
给出路程x,请计算所需的车费。
输入
输入共一行,两个数,中间用空格隔开;
第一个数是整数,表示路程;
第二个数是整数,1表示白天,0表示夜间。
输出
输出共一行,一个数,表示所需的车费,保留两位小数。
样例输入
10 1
样例输出
22.50
# include<bits/stdc++.h>
using namespace std;
int x,m;
double ans;
int main(){
cin>>x>>m;
if(m==1){
if(x<=3) ans=9;
else if(x<=6) ans=9+1.5*(x-3);
else ans=9+4.5+2.25*(x-6);
printf("%.2lf\n",ans);
return 0;
}
if(m==0){
if(x<=3) ans=9;
else if(x<=6) ans=9+1.75*(x-3);
else ans=9+5.25+2.5*(x-6);
printf("%.2lf\n",ans);
return 0;
}
return 0;
}
问题 H: 门牌号
题目描述
一天,班里的同学润润邀请宣宣到家里去玩,润润的家位于胡家胡同。这条胡同的门牌号是从1开始顺序编号,润润说:“其余各家的门牌号之和减去我家的门牌号,恰好等于n。”
告诉你n,请你帮宣宣计算一下:润润家的门牌号以及这个胡同里总共至少有多少户人家。
输入
输入共一行,一个正整数 n。输入数据保证有解。
输出
输出共一行,包含两个正整数,分别是润润家的门牌号及总共至少有多少家,中间用一个空格隔开。
样例输入
100
样例输出
10 15
# include<bits/stdc++.h>
using namespace std;
long long ans,m,n,s,i;
double l;
int main(){
scanf("%lld",&n);
m=1;
while(1){
m++;
if(m*m+m>n*2) {
s=(m*(m+1))/2;
for(i=1;i<=m;i++)
if(s-2*i==n) {ans=i;break;}
if(i<=m) break;
}
}
cout<<ans<<" "<<m<<endl;
return 0;
}
问题 I: 上课时间
题目描述
现在,小学实行双休日(好幸福!)。
以前,周六的上午也是要上课滴:周一到周五上午四节课,下午两节课;
周六上午还要上4节课,下午才开始休息。
已知每节课40分钟。
给你n,请你从周一开始算起,n天的上课时间是多少分钟?
输入
输入共一行,一个正整数 n,表示天数。
输出
输出共一行,包含一个正整数,表示总上课时间t。
样例输入
9
样例输出
1840
# include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,sum,ans,res,cnt;
int main()
{
cin>>n;
res=n/7;cnt=n%7;
ans=res*34;
for(ll i=1;i<=cnt;i++)
{
if(i==6) ans+=4;
else ans+=6;
}
printf("%lld",ans*40);
return 0;
}
问题 J: 数链
题目描述
现在我们有这样一个数链问题如下:
1.输入一个正整数 n;
2.输出 n;
3.如果 n=1 则结束;
4.如果 n 是奇数则 n 变为 3n+1,否则 n 变为 n/2;
5.转入第 2 步。
例如输入的正整数 n=22,应该会输出如下的数链:
22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
我们推测:对于任意一个正整数,经过上述算法最终都会得到 1。
对于给定的正整数 n,我们把得到的数链中数的个数称为 n 的链长,例如
22 的链长是 16。
对于给定的任意一对正整数 a 和 b,求出 a 与 b 之间的最长链长,当然这
个最长的链长是由 a 和 b 之间的一个正整数产生的,包括 a 和 b。
输入
输入共一行,两个用空格隔开的正整数 a,b(a<b)。
输出
输入供一行,一个数,a 与 b 之间的最长链长。
样例输入
1 10
样例输出
20
# include<bits/stdc++.h>
using namespace std;
int ans,m,n,s,i,res;
double l;
int main(){
cin>>n>>m;
for(int i=n;i<=m;i++){
res=1;s=i;
while(1){
if(s==1) break;
if(s&1) s=3*s+1,res++;
else s=s/2,res++;
}
ans=max(ans,res);
}
cout<<ans<<endl;
return 0;
}
问题 K: 读书活动
题目描述
最近小明买了一本非常有趣的书。他知道,把这本书读完需要t秒。小明想要尽可能快地完成阅读。
但他每天可能有一些工作和其他事情要做。未来几天,如果有空闲时间,他就可以进行阅读。请你帮助小明确定阅读完成的最低天数(从第一天开始最少需要到第几天)。
小明保证自己可以在不超过n天内读完这本书。
请记住每一天有86400秒。
输入
第一行包含两个整数n(1≤n≤100)和t(1≤t≤106),表示天数和读的书所需的时间。
第二行包含n个整数ai(0≤ai≤86400),表示未来几天他每天需要工作和做其他事情的时间。
输出
打印出最少需要到第几天,小明可以完成阅读本书。
确保答案不超过n。
样例输入
2 2
86400 86398
样例输出
2
# include<bits/stdc++.h>
using namespace std;
int ans,m,n,s,i,res,x;
double l;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>x;
if(x<86400) m=m-86400+x;
if(m<=0) {
cout<<i<<endl;
return 0;
}
}
return 0;
}
问题 L: 石头,剪刀,布
题目描述
小明和佳佳最近热衷于一个新游戏,叫做“石头剪刀布”,游戏规则我们都很熟悉:石头>剪刀,剪刀>布,布>石头。而老师每天最大的乐趣之一,就是看他俩玩这个游戏。小明和佳佳每天会进行N轮这样的游戏。然而不幸的是,小明和佳佳是编程高手,他们对操作进行了加密。虽然老师能看到他们做出了什么选择,他却不能辨认出他俩的选择代表的到底是石头还是剪刀或者是布。他们的三种选择分别用标号1、2、3表示。三个标号分别代表不同的选择(可能是剪刀、石头或者是布?)。现在给出N轮这种游戏,请你帮助老师统计,小明能够获胜的最大场数是多少。
输入
第一行输入一个数N(1≤N≤100)。表示游戏进行的轮数。
接下来的N行,每行输入2个数(1,2或者3)中间用空格分开,表示小明和佳佳分别出的是什么。第一个数表示小明出的选择。
输出
请输出小明能够获胜的最大场数。
样例输入
5
1 2
2 2
1 3
1 1
3 2
样例输出
2
因为就六种情况,开一个二维数组,举一个例子就能懂……
假如1是石头,2是剪刀,3是布
那么 line[1][2] line[2][3] line[3][1] 就是该种情况下三种胜利
接下来就枚举6种不同情况下最大值就好啦。
# include<bits/stdc++.h>
using namespace std;
int n,u,v,ans,line[10][10],cnt[10];
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
n=read();
for(int i=0;i<n;i++){
u=read();v=read();
line[u][v]++;
}
cnt[1] = line[1][2]+line[2][3]+line[3][1];
cnt[2] = line[1][3]+line[2][1]+line[3][2];
cnt[3] = line[2][1]+line[1][3]+line[3][2];
cnt[4] = line[2][3]+line[3][1]+line[1][2];
cnt[5] = line[3][1]+line[1][2]+line[2][3];
cnt[6] = line[3][2]+line[1][3]+line[2][1];
for(int i=1;i<=6;i++){
ans=max(ans,cnt[i]);
}
cout<<ans<<ednl;
return 0;
}
问题 M: 数字删除
题目描述
小明最近在研究一个数字删除游戏,正要考考佳佳。游戏规则如下
给定一个正整数,去掉其中若干个数字后剩下的数字按原左右次序将组成一个新的正整数。请问最少删去几个数字,能够使得这个新的正整数合法(不含前导0)且是3的倍数。
小明写下的数字太大,佳佳一时处理不了。请你帮他写一个程序处理出结果吧!
输入
第一行一个整数n(n≤5),表示小明写下了n正整数
第2~n+1行每行一个正整数Ai(Ai≤10100000),数字的长度可能达到100001位。
输出
共n行,每行一个整数,表示最少删去的数字的个数。如果没有合法的方案,请输出“ERR”(不含引号)。
样例输入
3
1234
1000
2
样例输出
1
3
ERR
补题的,看起来挺烦,仔细看一遍都能看懂
# include<bits/stdc++.h>
using namespace std;
int n,l,m;
string s;
int main(){
cin>>n;
while(n--){
cin>>s;
l=s.size();m=0;
for(int i=0;i<l;i++)
m+=s[i]-'0';
if(l<=2&&m%3!=0){ //如果长度小于3
if(l==1) cout<<"ERR"<<endl; //长度是1并且不是3的倍数
else if((s[0]-'0')%3!=0&&(s[0]-'0')%3!=0) cout<<"ERR"<<endl; //长度是2并且两位都不是3的倍数
else cout<<1<<endl; //1位是3的倍数
}
//依次判断mod出来是0,1,2中哪一种
else if(m%3==0) cout<<0<<endl;
else if(m%3==1) { //从后往前找,找到第一个%3=1的就删除,再判断是否有前导0和超过长度的边界情况。
int num1=0,num2=0;
for(int i=s.size()-1;i>=0;i--)
if((s[i]-'0')%3==1){
num1++;
s.erase(i,1);
break;
}
if(num1==1) {
while(s[0]=='0'){ //删去前导0,每删一个数num1++
s.erase(0,1);
num1++;
}
if(num1<l) cout<<num1<<endl;//如果num1<s.size(),直接输出num1
else cout<<l-1<<endl;//否则就输出l-1
}
//num1如果是0说明有两个数的和mod3=1:比如4=2+2,2%3=2 ,固需要从后找两个mod3=2的
else{
for(int i=l-1;i>=0;i--)
if((s[i]-'0')%3==2){
num2++;s.erase(i,1);
if(num2==2) break;
}
if(num2==2) {
while(s[0]=='0') {
s.erase(0,1);
num2++;
}
if(num2<l) cout<<num2<<endl;
else cout<<l-1<<endl;
}
}
}
//之后同理
else if(m%3==2){
int num1=0,num2=0;
for(int i=l-1;i>=0;i--)
if((s[i]-'0')%3==2){
num1++;
s.erase(i,1);
break;
}
if(num1==1) {
while(s[0]=='0')
s.erase(0,1),num1++;
if(num1<l) cout<<num1<<endl;
else cout<<l-1<<endl;
}
else{
for(int i=l-1;i>=0;i--)
if((s[i]-48)%3==1){
num2++;
s.erase(i,1);
if(num2==2) break;
}
if(num2==2){
while(s[0]=='0')
s.erase(0,1),num2++;
if(num2<l) cout<<num2<<endl;
else cout<<l-1<<endl;
}
}
}
}
}
问题 N: 运动会I
题目描述
小F和大F开了一所幼儿园,春天到了,幼儿园要举办一场运动会!
幼儿园里有N个小朋友,运动会里有M个项目可供选择,每个小朋友都对M个项目有一定的喜好程度。对于第i个小朋友,他第j喜欢的项目是aij。并且保证对于每个小朋友,他都不会有两个一样喜欢的项目。
幼儿园的园长小F和副园长大F对运动会的事情头疼不已,她们希望玩的人数最多的项目玩的人数最少,否则她们在最受欢迎的项目举行时会忙不过来。她们希望从M个项目中选出若干个项目在运动会中举行(可以全选,但不能一个也不选),每个小朋友会且仅会玩一个项目,并且他玩的项目一定是举行的项目中他最喜欢的。
很不幸,今天幼儿园停电了,电脑不能用,小F和大F决定将这个问题交给聪明的你,请你求出玩的人数最多的项目玩的人数的最小值。
输入
第1行两个整数N和M(1≤N,M≤300),表示小朋友的个数和备选运动项目的个数。
第2至N+1行,每行M 个整数。第i+1行的第j个整数表示aij,表示第i个小朋友第j喜欢的项目。保证ai1…aiM是1…M的一个排列。
输出
一个整数,表示玩的人数最多的项目玩的人数的最小值。
样例输入 Copy
4 5
5 1 3 4 2
2 5 3 1 4
2 3 1 4 5
2 5 4 3 1
样例输出 Copy
2
提示
一种最优方案是选择举行1,3,4 三个项目,这样的话,4个小朋友玩的项目分别是1,3,3,4,玩的人数最多的项目是3,有2个人玩,所以答案是2。
待补。