统计完全数个数、扑克牌大小
题目要求:
<1>.完全数就是所有约数之和等于自身的数
<2>.给定一个数m,找出m以内所有完全数的个数
解题思路:
<1>.先写一个判断是不是完全数的函数
<2>.再写一个循环从1循环到m,是完全数就count++
<3>.输出count
代码示例:
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
bool isPerferctNum(int num)
{
int sum = 0;
vector<int> v;
for (int i = 1; i < num; ++i)
{
if ((num%i) == 0)
{
v.push_back(i);
}
}
for (int i = 0; i < v.size(); ++i)
{
sum += v[i];
}
if (sum == num)
{
return true;
}
return false;
}
int FindPerNum(int n)
{
int count = 0;
for (int i = 0; i < n;++i)
{
if (isPerferctNum(i+1) == true)
{
count++;
}
}
return count;
}
int main()
{
int n;
while (cin >> n)
{
cout << FindPerNum(n) << endl;
}
system("pause");
return 0;
}
题目要求:
<1>.输入两手牌,两手牌之间用“-”连接,每手牌的每张牌以空格分隔,“-”两边没有空格,如4 4 4 4-joker JOKER
<2>.输出两手牌中较大的那手,不含连接符,扑克牌顺序不变,仍以空格隔开;如果不存在比较关系则输出ERROR
基本规则:
(1)输入每手牌可能是个子,对子,顺子(连续5张),三个,炸弹(四个)和对王中的一种,不存在其他情况,
由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比
较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子)
(3)大小规则跟大家平时了解的常见规则相同,个子,对子,三个比较牌面大小;顺子比较最小牌大小;炸弹大
于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;
(4)输入的两手牌不会出现相等的情况。
答案提示:
(1)除了炸弹和对王之外,其他必须同类型比较。
(2)输入已经保证合法性,不用检查输入是否是合法的牌。
(3)输入的顺子已经经过从小到大排序,因此不用再排序了
解题思路:
<1>.各种if elseif往上堆,一条条判断…
<2>.虽说已ac,但是我写的也太菜了…等答案等答案…
感觉我多写了两个else if,算了等答案再修改…
代码示例:
#include<iostream>
#include<string>
using namespace std;
void ComPare(string& A, string& B)
{
string s = "345678910JQKA2";
if (A == "joker JOKER" || B == "joker JOKER")
{
cout << "joker JOKER" << endl;
}
else if (A.size() == 7 && B.size() != 7)
{
cout << A << endl;
}
else if (B.size() == 7 && A.size() != 7)
{
cout << B << endl;
}
else if ((A.size() == B.size()))
{
if (A == "JOKER" || B == "JOKER")
{
cout << "JOKER" << endl;
}
else if ((A == "joker"&&B != "JOKEr") || (B == "joker"&&A != "JOKER"))
{
cout << "joker" << endl;
}
if (s.find(A[0]) > s.find(B[0]))
{
cout << A << endl;
}
else
{
cout << B << endl;
}
}
else if ((A.size() == 2 && B.size() == 1) ||
(B.size() == 2 && A.size() == 1) ||
(A.size() == 5 && B.size() == 3) ||
(B.size() == 5 && A.size() == 3))
{
if (s.find(A[0]) > s.find(B[0]))
{
cout << A << endl;
}
else
{
cout << B << endl;
}
}
else if (A.size() > 7 && B.size() > 7)
{
if (s.find(A[0]) > s.find(B[0]))
{
cout << A << endl;
}
else
{
cout << B << endl;
}
}
else
{
cout << "ERROR" << endl;
}
}
int main()
{
string s;
while (getline(cin, s))
{
int position = s.find('-');
string A = s.substr(0, position);
string B = s.substr(position + 1);
ComPare(A, B);
}
system("pause");
return 0;
}
反思:
在gcc编译器下,对于 int i = 3; printf("%d %d", ++i, ++i),运行输出为:5 5
main()
{
char str[]="Geneius";
print (str);
}
print(char *s)
{
if(*s)
{
print(++s);
printf("%c",*s);
}
}
下面代码的输出是suiene
考察递归, * s指向G的时候调用print,++s,s指向e…最终*s为空,递归结束,相当于从右往左打印到e
#include <iostream>
using namespace std;
int main(void)
{
const int a = 10;
int * p = (int *)(&a);
*p = 20;
cout<<"a = "<<a<<", *p = "<<*p<<endl;
return 0;
}
编译器优化的结果,编译器在处理 const int a = 10;这句时 没有为a分配内存赋值
而是在加入了符号表,后续引用a时有些类似#define a 10这样处理,所以出现了同地址两个值
Widget f(Widget u)
{
Widget v(u);
Widget w=v;
return w;
}
main()
{
Widget x;
Widget y=f(f(x));
}
y=f(f(x)) 有两层 f() ,为了说明过程,把里面的一层标明为 f_1 ,外面一层标明为 f_2
则 7 次调用分别是:
x -> f_1 的 u
f_1 的 u -> f_1 的 v
f_1 的 v -> f_1 的 w
f_1 的 w -> f_2 的 u
f_2 的 u -> f_2 的 v
f_2 的 v -> f_2 的 w
f_2 的 w -> y
struct Test
{
Test( int ) {}
Test() {}
void fun() {}
};
void main( void )
{
Test a(1);
a.fun();
Test b();
b.fun();
}
Test b();—>调用一个名为b的函数,返回值类型为Test,并不是创建了一个Test类型的对象b
#include<iostream>
using namespace std;
class Base
{
public:
virtual int foo(int x)
{
return x * 10;
}
int foo(char x[14])
{
return sizeof(x)+10;
}
};
class Derived : public Base
{
int foo(int x)
{
return x * 20;
}
virtual int foo(char x[10])
{
return sizeof(x)+20;
}
};
int main()
{
Derived stDerived;
Base *pstBase = &stDerived;
char x[10];
printf("%d\n", pstBase->foo(100) + pstBase->foo(x));
return 0;
}
pstBase->foo(100)调用基类的foo但是同名隐藏,所以调用的是派生类的foo,结果为2000
pstBase->foo(x),调用基类的foo,指针在32位操作系统下大小为4,所以输出2014
virtual int foo(int x),基类的虚函数
int foo(char x[14]),基类虚函数的重载
virtual int foo(char x[10]),派生类自己定义的虚函数,只在派生类的子类中有用,干扰选项
<1>.牌数相同时,只需要比较第一张牌,只需要做到10把其他数字大就可以
<2>.王炸已经单独讨论了,所以牌数不同谁是炸弹输出谁
<3>.不满足比较条件的直接输出ERROR
如果做到逻辑清晰,也不是很难…
正确代码示例:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
string ComPareCard(string S)
{
if (S.find("joker JOKER") != string::npos)
{
return "joker JOKER";
}
else
{
int pos = S.find('-');
string A = S.substr(0, pos);
string B = S.substr(pos + 1);
//获取空格的个数,牌数为空格数+1
int C1 = count(A.begin(), A.end(), ' ');
int C2 = count(B.begin(), B.end(), ' ');
string A1 = A.substr(0, ' ');
string B1 = B.substr(0, ' ');
string s = "345678910JQKA2jokerJOKER";
if (C1 == C2)
{
cout << (s.find(C1) > s.find(C2) ? C1 : C2) << endl;
}
else
{
if (C1 == 3)
{
return A1;
}
else if (C2 == 3)
{
return B1;
}
else
{
return "ERROR";
}
}
}
}
int main()
{
string S;
while (getline(cin, S))
{
cout << ComPareCard(S) << endl;
}
system("pause");
return 0;
}
杨辉三角变形、超长整数加法
题目要求:
<1>.求第N行,第一个偶数出现的位置
<2>.如果没有偶数,则输出-1
解题思路:
<1>.我一开始以为是编程题…没做出来…
<2>.结果看到别人答案居然是找规律??
这样是不是不太合适…应该还是用正常的方法…等答案…
代码示例:
#include<iostream>
using namespace std;
int main()
{
int n;
while (cin >> n)
{
if (n <= 2)
{
cout << -1 << endl;
}
else if (n % 2 != 0)
{
cout << 2 << endl;
}
else if (n % 4 == 0)
{
cout << 3 << endl;
}
else
{
cout << 4 << endl;
}
}
return 0;
}
题目要求:
<1>.输入两个字符串数字
<2>.输出相加后的结果,string型
解题思路:
<1>.针对长短不一的对齐问题,把短的那个补到一样长,使用resize
<2>.从末尾开始相加,flag作为进位标志
<3>.相加的时候-‘0’,把相加好的结果转为char型存入C
<4>.每一位相加的结果%10就是进位的值,比如21,进位就是2
<5>.最后把C逆置,输出C
代码示例:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
string AddLongInt(string A, string B)
{
string C;
if (A.size() > B.size())
{
int n = A.size() - B.size();
while (n)
{
B.insert(B.begin(), '0');
n--;
}
}
else
{
int n = B.size() - A.size();
while (n)
{
A.insert(A.begin(), '0');
n--;
}
}
int flag = 0;
for (int i = A.size() - 1; i >= 0; --i)
{
int temp = (A[i] - '0') + (B[i] - '0') + flag;
C += char((temp % 10) + '0');
flag = temp / 10;
}
if (flag == 1)
{
C += '1';
}
//for (auto& e : C)
//{
// e += '0';
//}
reverse(C.begin(),C.end());
return C;
}
int main()
{
string A;
string B;
while (cin >> A >> B)
{
cout << AddLongInt(A, B) << endl;
}
system("pause");
return 0;
}
反思:
<1>.正确做法就是先把杨辉三角弄出来
<2>.按照题目意思,可以发现第n行有2n - 1个元素,第i,j元素等于上一行第j - 2,j - 1,j三列元素之和
<3>.每一行的第一列和最后一列都为1,如果是第二列,则只是两个元素之和
<4>.然后慢慢找,找到就输出
正确代码示例:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n, m;
while (cin >> n)
{
m = 2 * n - 1;
vector<vector<int>> v(n, vector<int>(m, 0));
v[0][0] = 1;
for (int i = 1; i < n; ++i)
{
//第一列和最后一列都是1
v[i][0] = v[i][2 * i] = 1;
for (int j = 1; j < 2 * i; ++j)
{
//第二列,只是两个元素的和
if (j == 1)
{
v[i][j] = v[i - 1][j - 1] + v[i - 1][j];
}
else
{
//第i,j元素等于上一行第j-2,j-1,j三列元素之和
v[i][j] = v[i - 1][j - 2] + v[i - 1][j - 1] + v[i - 1][j];
}
}
}
int k;
for (k = 0; k < m; ++k)
{
if (v[n - 1][k] % 2 == 0 && v[n - 1][k] != 0)
{
cout << k + 1 << endl;
break;
}
}
if (k == m)
{
cout << -1 << endl;
}
}
return 0;
}
统计兔子、字符串通配符
题目要求:
<1>.一只兔子,出生之后每三个月生一只兔子,小兔子长到三个月又生一只小兔子,假设兔子都不死
<2>.输入一个int型表示月份
<3>.输出兔子总数int型
解题思路:
斐波那契数列的应用
代码示例:
#include<iostream>
using namespace std;
int GetCount(int n)
{
if(n==1||n==2)
{
return 1;
}
else
{
return GetCount(n-1)+GetCount(n-2);
}
}
int main()
{
int n;
while(cin>>n)
{
cout<<GetCount(n)<<endl;
}
return 0;
}
题目要求:
<1>.输入一个带通配符的字符串在输入一个需要匹配的字符串
<2>.输出匹配结果
解题思路:
<1>.牛客网的测试用例好像不全,我第一次ac的代码我自测都有问题…
<2>.之后改了一下性能变差了,但是应该是都可以匹配了…
<3>.就是分情况判断…代码很垃圾…等答案…学…
代码示例:
#include<iostream>
#include<string>
using namespace std;
bool stringMatch(string A, string B)
{
//te?t*.*
//txt12.xls
int i = 0;
for (i; i < A.size(); ++i)
{
for (int j = 0; j < B.size(); ++j)
{
if (A[i] == B[j])
{
i++;
continue;
}
else if (A[i] == '?')
{
i++;
continue;
}
//a.*
//a.abc
else if (A[i] == '*'&&i == A.size() - 1)
{
break;
}
// *.a
// abc.a
else if (A[i] == '*'&&A[i + 1] == '.')
{
i = A.find('.') + 1;
j = B.find('.');
continue;
}
else if (A[i] == '*')
{
i++;
continue;
}
else
{
return false;
break;
}
}
}
if (i >= A.size())
{
return true;
}
return false;
}
int main()
{
string A;
string B;
while (cin >> A >> B)
{
if (stringMatch(A, B) == true)
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
}
system("pause");
return 0;
}
汽水瓶、查找两个字符串重复最大字串
题目要求:
<1>.商店规定三个空汽水瓶可以换一瓶汽水,可以向老板借
<2>.输入文件最多包含10组测试数据,每个数据占一行,表示小张手上的空汽水瓶数
<3>.n=0表示输入结束,你的程序不应当处理这一行
<4>.对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数.如果一瓶也喝不到,输出0
解题思路:
<1>.对于大佬的数学分析可得,喝的汽水数量等于瓶数/2,这种思路,太难了…
<2>.使用递归求解,n == 1喝不到,n == 2只能喝一瓶
<3>.n>2的时候,return GetDrink(n-2)+1;
代码示例:
#include<iostream>
using namespace std;
int GetDrink(int n)
{
if(n==1)
{
return 0;
}
else if(n==2)
{
return 1;
}
else
{
return GetDrink(n-2)+1;
}
}
int main()
{
int n;
while(cin>>n)
{
if(n==0)
{
break;
}
else
{
cout<<GetDrink(n)<<endl;
}
}
return 0;
}
题目要求:
<1>.查找两个字符串a,b中的最长公共子串.若有多个,输出在较短串中最先出现的那个
<2>.输入两个字符串
<3>.返回重复出现的字符
解题思路:
<1>.暴力破解…从第一个字符开始逐个字符增加取子串,如果在字符串B中出现就保存起来
<2>.取子串一定要从头开始逐个增加取,如果从头开始取最大的逐个递减,找到的子串可能不是最先出现的
<3>.find的返回值是int类型,是字符串的下标,如果返回npos代表没找到
<4>.出现长度比之前保存的大的就替换
<5>.最后输出找到的子串
代码示例:
#include<iostream>
#include<string>
using namespace std;
string FindSameString(string A, string B)
{
if (A.size() > B.size())
{
swap(A, B);
}
string s;
//for (int i = A.size(); i > 0; --i)
for (int i = 0; i < A.size(); ++i)
{
//for (int j = 0; j < A.size(); ++j)
for(int j = i; j<A.size(); ++j)
{
string tmp = A.substr(i, j - i + 1);
//find返回的是字符串的下标,没找到返回npos
if (B.find(tmp) == string::npos)
{
continue;
}
else if (tmp.size()>s.size())
{
s = tmp;
}
}
}
return s;
}
int main()
{
string A;
string B;
while (cin >> A >> B)
{
cout << FindSameString(A, B) << endl;
}
system("pause");
return 0;
}
字符串反转、公共字串计算
题目要求:
<1>.输入N个字符
<2>.输出反转过后的字符
解题思路:
string中提供的reverse方法
代码示例:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
string A;
while(cin>>A)
{
reverse(A.begin(),A.end());
cout<<A<<endl;
}
return 0;
}
题目要求:
<1>.计算两个字符串的最大公共字串的长度,字符不区分大小写
<2>.输入两个字符串
<3>.输出一个整数
解题思路:
<1>.前面做过查找最大公共字串,这个题就是输出的不是公共字串,输出它的size
<2>.暴力破解,从最大的递减查,是公共字串就保存起来,遇到更大的就替换
<3>.字符不区分大小写,所以全部转成大写
代码示例:
#include<iostream>
#include<cctype>
#include<string>
#include<algorithm>
using namespace std;
int GetCommonStrLengrh(string A,string B)
{
transform(A.begin(),A,end(),A.begin(),towupper);
transform(B.begin(),B,end(),B.begin(),towupper);
string A1=A.size()<B.size()?A:B;
string B1=A.size()<B.size()?B:A;
string C;
string tmp;
for(int i=0;i<A1.size();++i)
{
for(j=A1.size()-1;j>=0;--j)
{
tmp=A1.substr(i,j);
if(B1.find(tmp)!=string::npos)
{
if(tmp.size()>C.size())
{
C=tmp;
}
}
}
}
return C.size();
}
int main()
{
string A;
string B;
while(cin>>A>>B)
{
cout<<GetCommonStrLengrh(A,B)<<endl;
}
return 0;
}