题解_20210816
- 字符串, 数学逻辑,函数递归
P7694 [COCI2009-2010#4] AUTORI
【题目描述】
科学论文会大量引用一些早期的著作,因此在一个论文中出现两种不同的命名约定并不少见。这两种不同的命名约定分别是:
长变体,由每个作者姓氏的完整单词由连字符连接而成,例如 Knuth-Morris-Pratt。
短变体,仅由每个作者姓氏的第一个字符拼接而成,例如 KMP。
现在,你发现了一篇论文中同时使用了长变体和短变体这两种命名约定,这让你感到很不愉快,因此你想编写一个程序,将所有的长变体变为短变体。
输入格式:
输入仅一行,一个字符串,代表在论文中出现的长变体。
每一个长变体中的单词开头一定是大写字母。
输出格式:
输出仅一行,一个字符串,代表长变体经过变换以后的短变体。
输入输出样例
输入:Knuth-Morris-Pratt
输出:KMP
输入:Mirko-Slavko
输出:MS
输入:Pasko-Patak
输出:PP
【数据范围】
对于所有数据,满足字符串的长度不超过 100,且仅包含大小写英文字母和连字符 -
【题解】直接输出首个字符,以及前个字符为'-'的字符即可。
#include<iostream>
#include<cstring>
using namespace std;
int main() {
string str; cin>>str;
for(int i=0; i<str.length(); i++){
if(i==0 || str[i-1]=='-'){
cout<<str[i];
}
}
return 0;
}
P6386 [COCI2007-2008#4] VAUVAU
【题目描述】
在一个小村子里,邮递员、送奶工、垃圾清理工每天早晨都面临着同样的难题:18 号房子的门前有两条看门狗。他们所不知道的是,这两条狗的表现是有迹可循的。
当一天开始时,其中一条狗会先暴躁 a 分钟,然后安静 b 分钟,而另一条狗则会先暴躁 c 分钟,然后安静 d 分钟。这两条狗在一天中会无限地重复上述行为。
给定这三个人到达 18 号房子的时刻,请求出该时刻有几条狗是处于暴躁状态的。
输入格式
第一行有四个整数,分别表示 a, b, c, d。
第二行有三个整数,分别表示邮递员到达的时刻 p,送奶工到达的时刻 m 和垃圾清理工到达的时刻 g。
输出格式
输出三行每行一个字符串,依次表示邮递员、送奶工、垃圾清理工到达时有几条狗处于暴躁状态。
如果没有狗处于暴躁状态,输出 none。
如果恰好有一条狗处于暴躁状态,输出 one。
如果两条狗都处于暴躁状态,输出 both。
输入输出样例
输入:
2 2 3 3
1 3 4
输出:
both
one
none
输入:
2 3 4 5
4 9 5
输出:
one
none
none
数据规模与约定:对于全部的测试点,保证 1≤a,b,c,d,p,m,g<1e3。
【题解】
对于本题目,或许第一眼会想到循环,但是其实不需要,因为我们只需要判断当人物在某个时间点到达该地时,狗是否在叫即可。当然,如果题目稍加变化,将数据量增加,就需要使用数组和循环来完成了。
由于狗的暴躁和冷静是循环的,也就是说一个周期进行一次,那么我们直接将人物到达该地点的时间缩短为一个周期以内,会发现结果是相同的,然后只需要判断,到达时间到底是在狗暴躁期内,还是冷静期内即可。但是注意暴躁期和冷静期的结束时间还是属于该期间的。
#include<iostream>
#include<cstring>
using namespace std;
int fun(int a, int b, int c, int d, int p){
int dog=0;
int r1 = p-p/(a+b)*(a+b);
int r2 = p-p/(c+d)*(c+d);
if(r1<=a && p%(a+b)!=0) dog++;
if(r2<=c && p%(c+d)!=0) dog++;
return dog;
}
void print(int dog){
if(dog==2) cout<<"both"<<endl;
else if(dog==1) cout<<"one"<<endl;
else cout<<"none"<<endl;
}
int main() {
int a,b,c,d,p,m,g;
cin>>a>>b>>c>>d>>p>>m>>g;
int p_dog = fun(a,b,c,d,p);
int m_dog = fun(a,b,c,d,m);
int g_dog = fun(a,b,c,d,g);
print(p_dog);
print(m_dog);
print(g_dog);
return 0;
}
P2036 [COCI2008-2009#2] PERKET
【题目描述】
Perket 是一种流行的美食。为了做好 Perket,厨师必须谨慎选择食材,以在保持传统风味的同时尽可能获得最全面的味道。你有 n 种可支配的配料。对于每一种配料,我们知道它们各自的酸度 s 和苦度 b。当我们添加配料时,总的酸度为每一种配料的酸度总乘积;总的苦度为每一种配料的苦度的总和。
众所周知,美食应该做到口感适中,所以我们希望选取配料,以使得酸度和苦度的绝对差最小。
另外,我们必须添加至少一种配料,因为没有任何食物以水为配料的。
输入格式
第一行一个整数 n,表示可供选用的食材种类数。
接下来 n 行,每行 2 个整数 si 和 bi,表示第 i 种食材的酸度和苦度。
输出格式
一行一个整数,表示可能的总酸度和总苦度的最小绝对差。
输入输出样例
输入
1
3 10
输出
7
输入
2
3 8
5 8
输出
1
输入
4
1 7
2 6
3 8
4 9
输出
1
数据规模与约定
对于 100% 的数据,有 1≤n≤10,且将所有可用食材全部使用产生的总酸度和总苦度小于1e9 ,酸度和苦度不同时为 1 和 0。
【题解】
先不考虑至少一种的情况,就可以直接对食材种类进行递归遍历,每种食材有选或不选两种情况,按要求取最小绝对差即可。
最后再处理,一定要选择一种的情况,如果发现甜度&苦度没有发生变化,则证明没有选择任何一种,这时候就退出,不需要这样的结果。
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
const int N=11;
int n,ans=1<<30;//给ans一个较大的数,相当于 1*pow(2,30)
int s[N], b[N];
void dfs(int m, int k, int x, int y){
if(m>n){
if(x==1 && y==0) return ; //处理无选择的情况
ans = min(ans, abs(x-y));
return;
}
dfs(m+1, k+1, x*s[m], y+b[m]);//选择
dfs(m+1, k, x, y);//不选择
}
int main() {
cin>>n;
for(int i=1; i<=n; i++) cin>>s[i]>>b[i];
dfs(1,1,1,0);//遍历第1种配料,选择第 1种配料,现有甜度,现有苦度
cout<<ans;
return 0;
}

浙公网安备 33010602011771号