目录
第一题
小艺改编字符串
题目描述
已知字符串str. 添加至少多少字符可以使得str变成回文串。
输入描述:
输入字符串s.(1<=len(str)<=100)
输出描述:
输出最小需要添加字符的数量。
输入样例:
abab
输出样例:
1
题解
#include<bits/stdc++.h>
using namespace std;
char s[1010],t[1010];
int dp[1010][1010];
int main()
{
scanf("%s",s);
int l=strlen(s);
for(int i=0,j=l-1;i<l;i++,j--)
t[i]=s[j];
for(int i=0;i<l;i++)
for(int j=0;j<l;j++)
if(s[i]==t[j])
dp[i+1][j+1]=dp[i][j]+1;
else
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
cout<<l-dp[l][l];
return 0;
}
第二题
小Q新式棋盘
题目描述
已知棋盘大小为n*n。 每个位置都有自己的权值q。 该棋盘中有多少对行权值和小于列权值和。
输入描述:
第一行输入整数n。(1<=n<=100)表示棋盘的大小 以下n行每行输入n个整数表示棋子的权值。(1<=a<=1000)
输出描述:
输出小Q的分值。
输入样例
3
1 2 3
1 2 3
1 2 3
输出样例
3
题解
#include<iostream>
#define N 10000
using namespace std;
int main(){
int str[110][110];
int arr[N],dp[N],t[N],a[N];
int n,m=0,sum=0,ans=0,g=0;
cin>>n;
for(int i=0;i<n;i++){
sum=0;
for(int j=0;j<n;j++){
cin>>str[i][j];
sum=sum+str[i][j];
}
arr[i]=sum;
}
for(int i=0;i<n;i++){
sum=0;
for(int j=0;j<n;j++){
sum=sum+str[j][i];
}
dp[i]=sum;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(arr[i]<dp[j])
ans++;
}
}
cout<<ans;
return 0;
}
第三题
莫名其妙的键盘
题目描述
有一个神奇的键盘,你可以用它输入a到z的字符,然而每当你输入一个元音字母(a,e,i,o,u其中之一)的时候,已输入的字符串会发生一次反转! 比方说,当前输入了tw,此时再输入一个o,此时屏幕上的字符串two会反转成owt。 现给出一个字符串,若用该键盘输入,有多少种方法可以得到?
输入描述:
一行一个字符串,长度不超过200,全部是由小写字母组成。
输出描述:
一个整数,代表方案数量
输入样例
ac
输出样例
1
题解
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
bool judge(char c) {
char s[6] = "aeiou";
for(int i = 0;i < 5;i++) {
if(c == s[i])
return true;
}
return false;
}
int dfs(string &s) {
int n = s.size();
if(n == 1) return 1;
if(judge(s[n-1])) {
if(!judge(s[0]))
return 0;
string g;
for(int i = n - 1;i;i--)
g=g+s[i];
return dfs(g);
}
string s1 = s.substr(0,n-1);
if(judge(s[0])) {
string g;
for(int i = n - 1;i;i--)
g=g+s[i];
return dfs(s1) + dfs(g);
}
return dfs(s1);
}
int main() {
string s;
cin>>s;
cout<<dfs(s)<<endl;
return 0;
}
第四题
扰乱字符串
题目描述
使用下面描述的算法可以扰乱字符串 s
得到字符串 t
:
- 如果字符串的长度为 1 ,算法停止
- 如果字符串的长度 > 1 ,执行下述步骤:
- 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串
s
,则可以将其分成两个子字符串x
和y
,且满足s = x + y
。 - 随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,
s
可能是s = x + y
或者s = y + x
。 - 在
x
和y
这两个子字符串上继续从步骤 1 开始递归执行此算法。
- 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串
给你两个 长度相等 的字符串 s1
和 s2
,判断 s2
是否是 s1
的扰乱字符串。如果是,返回 true
;否则,返回 false
。
输入样例:
s1 = "great", s2 = "rgeat"
输出样例
true
题解
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
static bool scramble(char *s1, int low1, int high1, char *s2, int low2, int high2)
{
if (high1 - low1 != high2 - low2)
{
return false;
}
else if (!memcmp(s1 + low1, s2 + low2, high1 - low1 + 1))
{
return true;
}
else
{
int i, c1[128] = {0}, c2[128] = {0};
for (i = low1; i <= high1; i++)
{
c1[s1[i]]++;
}
for (i = low2; i <= high2; i++)
{
c2[s2[i]]++;
}
if (memcmp(c1, c2, 128 * sizeof(int)))
{
return false;
}
else
{
int len = high1 - low1 + 1;
for (i = 1; i < len; i++)
{
if (scramble(s1, low1 + i, high1, s2, low2 + i, high2))
{
return true;
}
if (scramble(s1, low1 + i, high1, s2, low2, high2 - i))
{
return true;
}
}
return false;
}
}
}
static bool isScramble(char *s1, char *s2)
{
return scramble(s1, 0, strlen(s1) - 1, s2, 0, strlen(s2) - 1);
}
int main(int argc, char **argv)
{
if (argc != 3)
{
fprintf(stderr, "Usage: ./test s1 s2\n");
exit(-1);
}
printf("%s\n", isScramble(argv[1], argv[2]) ? "true" : "false");
return 0;
}
第五题
卖树苗
题目描述
植树节又到了,商家A和商家B为了卖出更多的树苗。
商家A有了新的决定:
购买树苗数量小于等于10棵,所有树苗按正常价格10元一棵收费;
购买树苗数量大于10且小于等于20棵,超出10棵以上的树苗按8.2元一棵收费,其余树苗按正常价格收费;
购买树苗数量大于20棵,超出20棵以上的树苗按7.5元一棵收费,10至20棵部分树苗按8.2元一棵收费,其余树苗按正常价格收费。
商家B决定:
所有树苗12元一棵,但是均打七折卖出。图图要代表班级去买树苗,要求输入图图需要购买的树苗棵数,输出在哪家商家购买更加划算及其所要花费的钱数。
输入描述
一行,一个整数,表示图图需要购买的树苗数量。
输入样例
30
输出样例
B 252
题解
#include <iostream>
using namespace std;
int main() {
double n, A, B;
cin >> n;
B = 12 * 0.7 * n;
if (n <= 10) {
A = 10 * n;
}
else if (n > 10 && n <= 20) {
A = 10 * 10 + (n - 10) * 8.2;
}
else {
A = 10 * 8.2 + (n - 20) * 7.5 + 10 * 10;
}
if (A < B) {
cout << "A " << A;
}
else {
cout << "B " << B;
}
return 0;
}