完全数计算
思路:
本题可以通过遍历每一个约数,求和,判断完全数。约数计算可以遍历sqrt(n)的范围。
代码:
#include<iostream>
using namespace std;
int main() {
int num;
cin >> num;
int SUM_OF_NUM = 0;
for (int ENUM = 1; ENUM <= num; ENUM++) {
int sum = 0;
for (int i = 1; i < ENUM; i++) {
if (ENUM % i == 0) {
sum += i;
}
}
if (sum == ENUM) {
SUM_OF_NUM++;
}
}
cout << SUM_OF_NUM;
return 0;
}
扑克牌大小
思路:
本题的题目意思是输入的只是这些类型中的一种,个子,对子,顺子(连续5张),三个,炸弹(四个)和对王。其实就是最多5张牌(顺子),最少1一张牌之间的比较。不存在其他情况。
- 首先判断是否有对王。对王最大。
- 然后由输入保证两手牌都是合法的,顺子已经从小到大排列,如果两手牌的数量相同那么就可以直接比较第一张牌即可。
- 如果两手牌的数量不相同,一定是有炸弹和对王,对王我们最开始就比较了,炸弹就看哪手牌的数量是4,那么就哪手牌大。
代码:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string FindMax(const string& line) {
if (line.find("joker JOKER") != -1)//string::npos
return "joker JOKER";
int dash = line.find('-');
//分开两手牌
string car1 = line.substr(0, dash);
string car2 = line.substr(dash + 1);
//获取两手牌的张数
int car1_cnt = count(car1.begin(), car1.end(), ' ') + 1;
int car2_cnt = count(car2.begin(), car2.end(), ' ') + 1;
//获取两手牌的各自第一张牌
string car1_first = car1.substr(0, car1.find(' '));
string car2_first = car2.substr(0, car2.find(' '));
//两手牌的类型相同
if (car1_cnt == car2_cnt) {
string str = "345678910JQKA2jokerJOKER";
if (str.find(car1_first) > str.find(car2_first))
return car1;
return car2;
}
//数量(类型)不相同
//而且car1是炸弹
if (car1_cnt == 4)
return car1;
//数量(类型)不相同
//而且car2是炸弹
else if (car2_cnt == 4)
return car2;
//以上情况都不满足
return "ERROR";
}
int main() {
string line, res;
while (getline(cin, line)) {
res = FindMax(line);
cout << res << endl;
}
return 0;
}
杨辉三角的变形
思路:
按照题目意思,可以发现第n行有2n - 1个元素,第i,j元素等于上一行第j - 2,j - 1,j三列元素之和,每一行的第一列和最后一列都为1,如果是第二列,则只是两个元素之和。
代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main() {
int n, m;
while (cin >> n) {
m = 2 * n - 1;
vector<vector<int>> dp(n, vector<int>(m, 0));
dp[0][0] = 1;
for (int i = 1; i < n; i++) {
//第一列和最后一列都为1
dp[i][0] = dp[i][2 * i] = 1;
for (int j = 1; j < 2 * i; ++j) {
if (j == 1)
//如果是第二列,则只是两个元素之和
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
else
//第i,j元素等于上一行第j - 2,j - 1,j三列元素之和
dp[i][j] = dp[i - 1][j - 2] + dp[i - 1][j - 1] + dp[i - 1][j];
}
}
int k;
for (k = 0; k < m; k++) {
if (dp[n - 1][k] % 2 == 0 && dp[n - 1][k] != 0) {
cout << k + 1 << endl;
break;
}
}
if (k == m)
cout << -1 << endl;
}
return 0;
}
由于牛客更新了测试用例,加强了内存限制,因此上述用例在运行时会超出内存限制,所以上述使用生成杨辉三角,然后在第n行上寻找偶数的方式已经不合适,故进行更正。
通过以上的数据分析规律为 {-1,-1,2,3,2,4,2,3,2,4,...}
,即第n行上偶数所在的下标。
前两行没有偶数输出-1,包括第三行在内之后的行数,偶数出现的位置是有规律的,都是2、3、2、4...
,这样循环往复。
代码:
#include<iostream>
#include<string>
using namespace std;
int main(int argc, char* argv[]) {
int nRow = 0;
while (cin >> nRow) {
int res = -1;
int myInt[] = {4, 2, 3, 2};
if (nRow > 2)
res = myInt[(nRow - 2) % 4];
cout << res << endl;
}
return 0;
}
计算某字符出现次数
思路:
首先,字符串中包含有空格,因此我们使用 getline 函数获取一行数据,而不用cin ,因为 cin 函数会默认以空格截断输入作为输入的结束.
其次,因为在计算字符出现次数中,要求是不区分大小写的,因此在处理过程中,如果输入的是小写字母,则计数不但要加上小写字母的计数,还要加上大写字母的计数,反之大写字母也是同样如此,而在 ascii 表中,大写字母和小写字母的差值是 32 ( 'a’的ascii值是97 ; 'A’的ascii值是65 )
最后,把输入的字符按需转化为大写,然后遍历输入的字符串,并按需转化为大写,如果与输入的要被查找的字符串相同,则计数器++。
代码:
#include<iostream>
#include<string>
using namespace std;
int main() {
string in_string = "";
char find;
int count = 0;
getline(cin, in_string);
cin >> find;
//转化为大写
if (find >= 97 && find <= 122) {
find -= 32;
}
//遍历in_string
for (auto& ch : in_string) {
//小写转大写
if (ch >= 97 && ch <= 122) {
ch -= 32;
}
if (ch == find) {
count++;
}
}
cout << count << endl;
return 0;
}
end