A
输入格式:
输入给出若干行由英文小写字母、空格、回车组成的文字,以一个特殊的符号 #
结束。题目保证输入不超过105 个字符。
输出格式:
在一行中输出 fight
出现的次数。
输入样例:
sleep eat fight fightfightfffighht fi
ght eat fight sleep fighting#
输出样例:
5
思路:string函数运用
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s;
long long c=0;
while(1)
{
getline(cin,s);
string ss;
if(s.size()>=5)
{
for(int i=0;i<=s.size()-5;i++)
{
ss=s.substr(i,5);
if(ss=="fight")c++;
}
}
if(s[s.size()-1]=='#')break;
}
cout<<c;
return 0;
}
B
关于数学定理证明,也有高下之分。最暴力的证明方法是“构造性证明”,即当需要证明某种解存在时,直接把解构造出来,而不是仅通过推理证明解之存在。
下面有一个定理:
设 ai(i=1,⋯,5)均为正实数。则一定存在 4 个互不相同的下标 i、j、k、l,使得 ∣ai/aj−ak/al∣<1/2。
作为程序员,就请你编写程序构造出正确的下标,验证这个结论。
输入格式:
输入在一行中顺序给出 5 个正实数。为保证计算中不产生浮点溢出,我们令输入的数字在 [10−10,1010] 区间内,且小数点后不超过 10 位小数。
输出格式:
在一行中首先输出使得定理结论成立的下标有多少套,随后输出最小的一套下标。数字间以 1 个空格分隔,行首尾不得有多余空格。
注:所谓下标集 i1,⋯,i4 小于下标集 j1,⋯,j4,是指存在 1≤k≤4 使得 il=jl 对所有 l<k 成立,且 ik<jk。
输入样例:
3.12 5.27 0.0007 9825.4413 10
输出样例:
18 1 4 3 2
思路:大模拟
#include <bits/stdc++.h>
using namespace std;
double s[10];
int ans=0;
double mn=1;
bool check(int i,int j,int k,int l)
{
return i!=j&&i!=l&&i!=k&&j!=l&&j!=k&&l!=k;
}
vector<int>an;
int main()
{
for(int i=1;i<=5;i++)cin>>s[i];
for(int i=1;i<=5;i++)
{
for(int j=1;j<=5;j++)
{
for(int k=1;k<=5;k++)
{
for(int l=1;l<=5;l++)
{
if(check(i,j,k,l)&&fabs(s[i]/s[j]-s[k]/s[l])<0.5)
{
ans++;
vector<int>aa;
aa.push_back(i);
aa.push_back(j);
aa.push_back(k);
aa.push_back(l);
if(an.size()==0)an=aa;
else an=min(aa,an);
}
}
}
}
}
cout<<ans;
for(auto i:an)cout<<" "<<i;
cout<<endl;
return 0;
}
C
本题的任务很简单:给定两个正整数 A 和 B,请你输出 A+B 的值。麻烦在于,两个整数不一定是 10 进制的。
已知一个 d 进制的 k 位正整数 ak−1⋯a1a0 的十进制值为 ∑i=0k−1aidi,其中每一位数字 0≤ai<d 且 ak−1=0。
输入格式:
输入分两行,分别给出两个正整数 A 和 B。每行格式为:
k a[k-1] ... a[1] a[0]
对应 d 进制的 k
位正整数 a[k-1]...a[1]a[0]
,数字间以 1 个空格分隔。题目保证 k
为不超过 104 的正整数,且每位数字 a[i]
为不超过 103 的非负整数,最高位 a[k]
不为 0。
输出格式:
求最小可能的进制下 A+B 的值。输出格式与输入格式相同,行首尾不得有多余空格。
输入样例:
3 31 28 16
4 1 5 6 18
输出样例:
4 2 5 3 2
样例解释:
根据输入,这两个数的最小可能的进制是 32,因为有一位数字是 31。按 32 进制求和,得到一个 4 位的 32 进制数 2 5 3 2。
思路:大模拟
#include <bits/stdc++.h>
using namespace std;
vector<int>a,b;
int main()
{
int mx=0;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
mx=max(x,mx);
a.push_back(x);
}
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
mx=max(x,mx);
b.push_back(x);
}
if(a.size()<b.size())
{
swap(a,b);
}
mx++;
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
int t=0;
for(int i=0;i<a.size();i++)
{
a[i]+=t;
if(i<b.size())a[i]+=b[i];
t=a[i]/mx;
a[i]%=mx;
}
reverse(a.begin(),a.end());
int len=a.size();
if(t)len++;
cout<<len;
if(t)cout<<" "<<t;
for(auto i:a)
{
cout<<" "<<i;
}
return 0;
}
D
一种机器人的行为是这样设计的:它的目标是从一个方形地图的南边移动到北边。当中途遇到障碍物时,它只能向西转向,然后移动到可以向北的时候,再转向北继续。
给定一张由 n×n 个方格子组成的正方形地图,机器人可以从地图的最底边(南边)下面的位置出发,目标是到达地图的最上边(北边)。(顺便说:地图的左边是西,右边是东。)
如果图中放置了障碍物,机器人是有可能落入陷阱的,即从某些位置出发,会永远无法到达北边。例如在下图中,如果机器人从 7 号或者 8 号位置出发,就会落入陷阱。
本题就请你指出那些会令机器人落入陷阱的位置。
注意:假设机器人可以走出地图边界,而围绕地图边界的所有格子都是空的,没有障碍物。如果机器人从地图东、西边界外的任意起点出发,都可以毫无障碍地到达北边,所以我们显然只需要考虑东、西边界内的起始位置(例如上图南边下面的位置 1~10)。此外,只要能到达北边,哪怕不在地图范围内也算是成功的(例如上图从位置 1、2 出发就会走出地图,但仍然能到达北边)。
输入格式:
输入第一行首先给出一个正整数 n (≤100),是地图的规模。随后 n 行,每行给出 n 个字符,或者是 0
代表此方格为空,或者是 1
代表此方格有障碍物。第一行对应的是北边,最后一行对应的是南边。
输出格式:
在一行中输出所有会令机器人落入陷阱的起始位置,按升序输出。这些位置从西向东顺次编号,编号从 1 开始。题目保证至少有一个输出。
一行中所有数字以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
10
0000000000
0000111010
1100100011
0000110001
0000000011
0000000000
0100000100
0001000000
0001000000
0001100000
输出样例:
7 8
思路:大模拟
#include <bits/stdc++.h>
using namespace std;
int n,a[110][110],f;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
char c;
cin>>c;
a[i][j]=c-'0';
}
getchar();
}
for(int i=1;i<=n;i++)
{
int x=i,y=n+1,r;
while(true)
{
if(y>0&&a[y-1][x]==0)
{
y-=1;
}
else if(x>0&&a[y][x-1]==0)
{
x-=1;
}
else if(y==0)
{
r=1;
break;
}
else
{
r=0;
break;
}
}
if(r==0)
{
if(f==1)cout<<" ";
cout<<i;
f=1;
}
}
return 0;
}
E
一个队列(先进先出结构)可以用两个堆栈(后进先出结构)来实现,方法如下:
- 从两个空堆栈 s1 和 s2 开始。
- 当元素 e 入队时,它实际上是被推入到 s1。
- 当我们需要出队时,首先检查 s2。如果 s2 是空的,则把 s1 中的元素全部导入 s2,即将每个元素从 s1 弹出后马上推入 s2。然后从 s2 中弹出元素 —— s2 顶端元素一定是第一个进入 s1 的,所以是应该出列的第一个元素。
假设每个堆栈的推入和弹出操作都用 1 个单位时间,请你给出每个出队操作所花的时间。
输入格式:
输入首先在一行中给出一个正整数 N(≤103),是操作数量。随后 N 行,每行按以下格式给出一个操作:
操作 元素
其中 操作
或者是 I
表示入队,或者是 O
表示出队。每个 I
后面跟的 元素
是一个不超过 106 的正整数。O
操作后面不跟任何元素。
题目保证至少有一个 O
操作。
输出格式:
对每个出队操作,在一行中输出出队的那个元素和这出队操作所花费的单位时间数量,其间以 1 个空格分隔,行首尾不得有多余空格。
若出队操作被调用时队列是空的,则在对应行中输出 ERROR
。
输入样例:
10
I 20
I 32
O
I 11
O
O
O
I 100
I 66
O
输出样例:
20 5
32 1
11 3
ERROR
100 5
思路:细节+模拟
#include <bits/stdc++.h>
using namespace std;
stack<int>a,b;
void solve()
{
char k;
cin>>k;
if(k=='I')
{
int x;
cin>>x;
a.push(x);
}
else
{
if(b.size())
{
cout<<b.top()<<" "<<"1"<<endl;
b.pop();
return ;
}
else
{
if(a.size())
{
while(a.size())
{
b.push(a.top());
a.pop();
}
cout<<b.top()<<" "<<b.size()*2+1<<endl;
b.pop();
}
else
{
cout<<"ERROR"<<endl;
}
}
}
}
int main()
{
int t;
cin>>t;
for(int i=1;i<=t;i++)
{
solve();
}
return 0;
}