欧几里得放蛋糕、字符型转为整数型
题目要求:
<1>.有W.H长和宽的网格,一个格子可以放一个蛋糕
<2>.但是任意两块蛋糕的欧几里得距离不能等于2
<3>.对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为:( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根
<4>.输入网格长宽w和h(1~1000)
<5>.输出可以放的蛋糕数
解题思路:
<1>.构建一个二维数组,一开始全部置为1
<2>.不可以放蛋糕的地方置为0
<3>.遍历数组中1的个数,就是放蛋糕的数量
<4>.输出count
代码示例:
#include <iostream>
using namespace std;
int main()
{
int W;
int H;
cin >> W;
cin >> H;
int array[1000][1000];
for (int i = 0; i < W; ++i)
{
for (int j = 0; j < H; ++j)
{
array[i][j] = 1;
}
}
int count = 0;
for (int i = 0; i < W ; ++i)
{
for (int j = 0; j < H ; ++j)
{
if (array[i][j] == 1)
{
count++;
if ((i + 2) < W)
{
array[i + 2][j] = 0;
}
if ((j + 2) < H)
{
array[i][j + 2] = 0;
}
}
}
}
cout << count << endl;
system("pause");
return 0;
}
vs中使用int array[1000][1000]会直接段错误,牛客网也偶尔会,但是Linux不会…
所以还是优先使用vector的好…避免空间浪费而且简单…
题目要求:
<1>.输入字符串,把字符串转换为整数
<2>.要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
<3>.输入一个字符串,包括数字字母符号,可以为空
<4>.如果是合法的数值表达则返回该数字,否则返回0
解题思路:
<1>.首先判断是否为空船,空就直接返回0,然后判断正负号,确定最后返回的是正数还是负数
<2>.如果不是0-9的字母就不管,是0-9的就转换
<3>.if(str[i]<=‘0’||str[i]>=‘9’)
<4>.转换方法为res=res*10+str[i]-‘0’;
<5>.乘10是为了把之前的变为更高位,str[i]是当前位的数字,减’0’是为了转为数字
<6>.最后输出res
代码示例:
#include <iostream>
#include <string>
using namespace std;
int StrToInt(string str)
{
if (str.empty())
{
return 0;
}
int flag = 1;
if (str[0] == '+')
{
flag = 1;
str[0] = '0';
}
else if (str[0] = '-')
{
flag = -1;
str[0] = '0';
}
int res = 0;
for (int i = 0; i < str.length(); ++i)
{
if (str[i] <= '0' || str[i] >= '9')
{
res = 0;
}
res = res * 10 + str[i] - '0';
}
return flag*res;
}
int main()
{
string s1;
getline(cin, s1);
cout << StrToInt(s1)<<endl;
system("pause");
return 0;
}
反思:
<1>.一定要把题意弄清楚,才能写代码
<2>.直接把静态二维数组修改成vector的二维数组
<3>.修改不能放蛋糕的位置元素为0需要在count++的if条件中
正确代码示例:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
long W,H;
cin>>W>>H;
vector<vector<int>> vv;
vv.resize(W);
for(auto& e:vv)
{
e.resize(H,1);
}
int count=0;
for(int i=0;i<W;++i)
{
for(int j=0;j<H;++j)
{
if(vv[i][j]==1)
{
count++;
if((i+2)<W)
{
vv[i+2][j]=0;
}
if((j+2)<H)
{
vv[i][j+2]=0;
}
}
}
}
cout<<count<<endl;
return 0;
}
斐波那契数列、括号合法性判断
题目要求:
<1>.输入一个整数N(1-1000000),求出将其变为斐波那契数的最小步数
<2>.输出需要的步数
解题思路:
<1>.创建一个循环,不断生成斐波那契数,将之为其比较
<2>.找到第一个大于那个斐波那契数,sep1=n-f(i)
<3>.往后找到小于的那个斐波那契数,sep2=f(i)-n
<4>.比较sep1和sep2的值,输出较小的那个
<5>.斐波那契数列使用循环写法,不然会导致堆栈溢出
代码示例:
#include<iostream>
int fib(int n)
{
int last2=1;
int last3=1;
int a=0;
if(n==1||n==2)
{
return 1;
}
for(int i=3;i<n;++i)
{
a=last3+last2;
last3=last2;
last2=a;
}
return a;
}
int main()
{
long long n;
cin>>n;
int sep1=0;
int sep2=0;
while(1)
{
if(n>fib(i))
{
sep1=n-fib(i);
}
if(n<fib(i+1))
{
sep2=fib(i+1)-n;
}
}
if(sep1<sep2)
{
cout<<sep1<<endl;
}
else
{
cout<<sep2<<endl;
}
return 0;
}
题目要求:
<1>.给定一个字符串A和它的长度n,判断其是否为一个合法的括号串
<2>.不可以带字母
解题思路:
<1>.测试样例居然只给了(),并没有涉及到[]和{}
<2>.我全都写完居然每次都是堆栈溢出,但是vs没有段错误,可以满足要求
<3>.用stack为什么不行呢?参考了一下别人的用string的可以
<4>.所以这个题思路是借鉴别人的
<5>.用一个B拷贝A,把B逆置,然后逐个对比
<6>.if((A[i] == ‘(’ && B[i] == ‘)’) || (A[i] == ‘)’ && B[i] == ‘(’) || (A[i] == ‘(’ && B[i] == ‘(’) ||(A[i] == ‘)’&& B[i]==’)’))
<7>.循环走完return true,else中return false;
代码示例:
class Parenthesis
{
public:
bool chkParenthesis(string A,int n)
{
if(n%2!=0)
{
return false;
}
string B(A);
reverse.(B.begin(),B.end());
for(int i=0;i<n;++i)
{
if((A[i]=='('&& B[i]==')')|| (A[i]==')'&& B[i]=='(')||
(A[i]=='('&& B[i]=='(')||(A[i]==')'&& B[i]==')'))
{
continue;
}
return false;
}
return true;
}
};
反思:
设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是(D)
A n=0;while(ch=getchar()!='\n')n++;
B n=0;while(getchar()!='\n')n++;
C for(n=0;getchar()!='\n';n++);
D n=0;for(ch=getchar();ch!='\n';n++);
D只获取了一次字符串
有如下类模板定义:()
template<class T> class BigNumber{
long n;
public:
BigNumber(T i):n(i){}
BigNumber operator+(BigNumber b)
{
return BigNumber(n+b.n);
}
};
已知b1,b2是BigNumber的两个对象,则下列表达式中错误的是(D)
3+3
b1+3
b1+b2
3+b1
此题考查的正是C++的运算符重载,+号被重载后相当于该类的一个成员函数了,出现该类对象(b1+)这种就是调用重载函数,+号后面的3或者b2就是参数,如果是3的话就会执行类型转化,将3变为BigNumber类型传给形参。至于D选项的错误我个人理解为+号左右两边的类型不匹配,3不是BigNumber的对象,调用+号的重载会编译失败
void main()
{
int a=1,b=0,c=-1,d=0;
d=++a||++b&&++c;
cout<<d<<endl;
return;
}
d=++a||++b&&++c中,++a||++b&&++c为逻辑表达式,其值要么为1,要么为0;
&& 运算符优先级高于 ||,所以最后算的是 || ,只要其中一个为真,表达式为真,表达式(++a)为2,不为0,为真,故d = 1;
假定一个类的构造函数为A(int aa,int bb){a=aa--;b=a*bb;},
则执行A x(4,5);语句后,x.a和x.b的值分别为(D)
A 20和5
B 3和15
C 5和4
D 4和20
a = aa–就是a = aa;aa–;这样的。所以a = 4,aa = 3之后b = a * bb=4 * 5 = 20;
评估报告里代码风格变成良了,代码规范也变成良了…要多注意…
正确代码示例:
#include<iostream>
using namespace std;
int main()
{
int sep1 = 0;
int sep2 = 0;
int f0 = 0;
int f1 = 1;
int f = 0;
int n;
while(cin >> n)
{
while (1)
{
f = f0 + f1;
f0 = f1;
f1 = f;
if (f < n)
{
sep1 = n - f;
}
else
{
sep2 = f - n;
break;
}
}
if (sep1 < sep2)
{
cout << sep1 << endl;
}
else
{
cout << sep2 << endl;
}
}
system("pause");
return 0;
}
<1>.遍历的是字符串,放进的是栈
<2>.对switch case语句用得太少,熟练度不够
class Parenthesis
{
public:
bool chkParenthesis(string A, int n)
{
stack<char> v;
for(auto e:A)
{
switch(e)
{
case '(':v.push(e);break;
case ')':
if(v.empty()||v.top()!='(')
{
return false;
}
else
{
v.pop();
}
break;
default:return false;break;
}
}
return true;
}
};
判断字符串是否满足两种排序、求最小公倍数
题目要求:
<1>.考拉忙着吃树叶,所以我们来帮忙判断字符串满不满足两种排序
<2>.输入一个整数,表示有多少个字符串,然后输入字符串
<3>.满足字典序,但不满足长度排序输出lexi…什么的
<4>.满足长度排序,但不满足字典序,输出lengths
<5>.既不满足长度也不满足字典序,输出none
<6>.既满足长度也满足字典序,输出both
解题思路:
<1>.创建一个vector v(n)
<2>.写出两种排序的检测算法
<3>.输入字符串的时候用cin就好,用getline是错的,v[0]位置放不进去
<4>.根据题目要求,进行输出
代码示例:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
bool CheckLength(vector<string> v,int n)
{
for(int i=1;i<n;++i)
{
if(v[i-1].length()<v[i].length())
{
continue;
}
return false;
}
return true;
}
bool CheckDic(vector<string> v,int n)
{
for(int i=1;i<n;++i)
{
if(v[i-1]<v[i])
{
continue;
}
return false;
}
return true;
}
int main()
{
int n;
cin>>n;
vector<string> v(n);
for(int i=0;i<n;++i)
{
cin>>v[i];
}
if(CheckDic(v,n)==true && CheckLength(v,n)==true)
{
cout<<"both"<<endl;
}
else if(CheckDic(v,n)==false && CheckLength(v,n)==true)
{
cout<<"lengths"<<endl;
}
else if(CheckDic(v,n)==true && CheckLength(v,n)==false)
{
cout<<"lexicographically"<<endl;
}
else
{
cout<<"none"<<endl;
}
return 0;
}
题目要求:
<1>.输入两个整数A,B
<2>.输出两个数的最小公倍数
解题思路:
<1>.如果A能整除B,那就输出A,如果B能整除A,那就输出B
<2>.求出两个数的最大公约数
<3>.然后,最小公倍数=两数乘积/最大公约数
<4>.这种常识我居然不知道,我是推了半天推出来的,一开始想的是大的那个数/最大公约数*小的那个数,通过70%
代码示例:
#include<iostream>
using namespace std;
int Func(int a,int b)
{
//80 40--->40
if(a%b==0)
{
return b;
}
//80 70 --->70 10-->10
return Func(b,a%b);
}
int main()
{
int A;
int B;
cin>>A>>B;
int C=Func(A,B);
if(A%B==0)
{
cout<<A<<endl;
}
else if(B%A==0)
{
cout<<B<<endl;
}
else
{
cout<<A*B/C<<endl;
}
return 0;
}
反思:
代码中有些地方根本就没用,要做到只写有用的代码…
正确代码示例:
#include<iostream>
using namespace std;
int Func(int A, int B)
{
int C;
while (C = A%B)
{
A = B;
B = C;
}
return B;
}
int main()
{
int A, B;
while (cin >> A >> B)
{
cout << A*B / Func(A,B) << endl;
}
system("pause");
return 0;
}
m*n的棋盘走法、另类的加法
题目要求:
<1>.输入两个数字n为横向的格子数,m为竖向的格子数
<2>.能往右和往下走,不能往左和往上走,从左上角走到右下角有多少种走法
<3>.输出正整数作为结果
解题思路:
<1>.使用vector创建一个二维数组,把第一行所有列置为1,把所有行第一列置为1
<2>.从vv[1][1]开始计算,vv[i][j]=vv[i-1][j]+vv[i][j-1];
<3>.返回最后的vv[m][n];
我当时绝对是脑子有病了,没用while(cin>>m>>n),导致0%通过…
代码示例:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int m,n;
while(cin>>m>>n)
{
vector<vector<int>> vv;
vv.resize(m+1);
for(auto& e:vv)
{
e.resize(n+1,0);
}
for(int i=0;i<=m;++i)
{
vv[i][0]=1;
for(int j=0;j<=n;++j)
{
vv[0][j]=1;
}
}
for(int i=1;i<=m;++i)
{
for(int j=1;j<=n;++j)
{
vv[i][j]=vv[i-1][j]+vv[i][j-1];
}
}
cout<<vv[m][n]<<endl;
}
return 0;
}
题目要求:
<1>.不可以使用加法运算符和其他运算符,完成加法操作
<2>.输入两个数A,B
<3>.输出相加的结果
解题思路:
<1>.使用位运算,A作为进位,B作为结果
<2>.最后输出B
代码示例:
#include<iostream>
using namespace std;
int main()
{
int A,B;
while(cin>>A>>B)
{
while(A!=0)
{
int tmp=B;
B=A^B;
A=A&tmp;
A<<=1;
}
return B;
}
return 0;
}
反思:
int fun(int a)
{
a^=(1<<5)-1;
return a;
}
fun(21)运行结果是(10)
当一个类的某个函数被说明为virtual,则在该类的所有派生类中的同原型函数_____?
A 只有 被重新说明时才识虚函数
B 只有被重新说明为virtual时才是虚函数
C 都不是虚函数
D 都是虚函数
他的回答: B (错误)
正确答案: D
目前还没弄到这…
class Test{
public:
int a;
int b;
virtual void fun() {}
Test(int temp1 = 0, int temp2 = 0)
{
a = temp1;
b = temp2;
}
int getA()
{
return a;
}
int getB()
{
return b;
}
};
int main()
{
Test obj(5, 10);
// Changing a and b
int* pInt = (int*)&obj;
*(pInt + 0) = 100;
*(pInt + 1) = 200;
cout << "a = " << obj.getA() << endl;
cout << "b = " << obj.getB() << endl;
return 0;
}
输出为 200 10
*(pInt+0)指向的是虚函数表指针
(pInt+1)和(pInt+2)分别指向a和b
<1>.两个数二进制位的异或运算相当于对应位相加,不考虑进位
<2>.二进制位的与运算相当于对应位相加之后的进位
<3>.两数相加=对应位相加的结果+进位的结果
正确代码示例:
class UnusualAdd
{
public:
int addAB(int A, int B)
{
int sum = 0;
int C = 0;
while (B != 0)
{
sum = A^B;
C = (A&B) << 1;
A = sum;
B = C;
}
return sum;
}
};
井字棋胜负检测、密码强度等级
题目要求:
<1>.给定一个井字棋的棋盘,1是玩家棋子,-1是对方棋子,0表示没棋子
<2>.一整行都是玩家棋子,或者一整列都是玩家棋子,或者两条对角线都是玩家棋子即为胜利
解题思路:
写的简洁点,就用个循环,不简洁就一条一条if判断
期待答案的高效算法,wotaicaile,我实在高效不起来…
代码示例:
#include<iostream>
#include <vector>
using namespace std;
class Board
{
public:
bool checkWon(vector<vector<int> > board)
{
if (board[0][0] == 1 && board[0][1] == 1 && board[0][2] == 1)
{
return true;
}
if (board[1][0] == 1 && board[1][1] == 1 && board[1][2] == 1)
{
return true;
}
if (board[2][0] == 1 && board[2][1] == 1 && board[2][2] == 1)
{
return true;
}
if (board[0][0] == 1 && board[1][0] == 1 && board[2][0] == 1)
{
return true;
}
if (board[0][1] == 1 && board[1][1] == 1 && board[2][1] == 1)
{
return true;
}
if (board[0][2] == 1 && board[1][2] == 1 && board[2][2] == 1)
{
return true;
}
if (board[0][0] == 1 && board[1][1] == 1 && board[2][2] == 1)
{
return true;
}
if (board[2][2] == 1 && board[1][1] == 1 && board[0][0] == 1)
{
return true;
}
return false;
}
};
题目要求:
<1>.输入一个字符串,根据要求算出得分,根据得分输出
<2>.一、密码长度:5 分: 小于等于4 个字符,10 分: 5 到7 字符,25 分: 大于等于8 个字符
二、字母:0 分: 没有字母,10 分: 全都是小(大)写字母,20 分: 大小写混合字母
三、数字:0 分: 没有数字,10 分: 1 个数字,20 分: 大于1 个数字
四、符号:0 分: 没有符号,10 分: 1 个符号,25 分: 大于1 个符号
五、奖励:2 分: 字母和数字,3 分: 字母、数字和符号,5 分: 大小写字母、数字和符号
最后的评分标准:>= 90: 非常安全,>= 80: 安全(Secure),>= 70: 非常强,>= 60: 强(Strong),
>= 50: 一般(Average),>= 25: 弱(Weak),>= 0: 非常弱
<3>.对应输出为: VERY_WEAK,WEAK,AVERAGE,STRONG,VERY_STRONG,SECURE,VERY_SECURE
解题思路:
<1>.先判断长度
<2>.在判断数字个数
<3>.在判断大写字母,小写字母
<4>.最后的就是符号
代码示例:
#include<iostream>
#include <string>
using namespace std;
int GetPwdSecurityLevel(string password)
{
int level = 0;
//长度检测
if (password.length() <= 4)
{
level += 5;
}
else if (password.length() >= 5 && password.length() <= 7)
{
level += 10;
}
else
{
level += 25;
}
//字母检测,符号检测,数字检测
int AZflag = 0;
int azflag = 0;
int sysflag = 0;
int count = 0;
int syscount = 0;
for (int i = 0; i < password.length(); ++i)
{
if (password[i] >= 'a'&&password[i] <= 'z')
{
azflag = 1;
}
else if (password[i] >= 'A'&&password[i] <= 'Z')
{
AZflag = 1;
}
else if (password[i] >= '0'&&password[i] <= '9')
{
count++;
}
else
{
sysflag = 1;
syscount++;
}
}
//字母得分
if (azflag == 1 && azflag == 1)
{
level += 20;
}
else if (azflag == 1 || AZflag == 1)
{
level += 10;
}
else
{
level += 0;
}
//数字得分
if (count == 0)
{
level += 0;
}
else if (count == 1)
{
level += 10;
}
else
{
level += 20;
}
//符号得分
if (syscount == 0)
{
level += 0;
}
else if (syscount == 1)
{
level += 10;
}
else
{
level += 25;
}
//奖励
if ((AZflag == 1 || azflag == 1) && count > 0 && sysflag == 0)//字母,数字有,无符号
{
level += 2;
}
else if ((AZflag == 1 || azflag == 1) && count > 0 && syscount > 0)//字母符号数字都有
{
level += 3;
}
else if ((AZflag == 1 && azflag == 1) && count > 0 && syscount > 0)//大小写字母,数字,符号
{
level += 5;
}
else
{
level += 0;
}
return level;
}
int main()
{
string pPasswordStr;
while (getline(cin, pPasswordStr))
{
GetPwdSecurityLevel(pPasswordStr);
if (GetPwdSecurityLevel(pPasswordStr) >= 90)
{
cout << "VERY_SECURE" << endl;
}
else if (GetPwdSecurityLevel(pPasswordStr) >= 80)
{
cout << "SECURE" << endl;
}
else if (GetPwdSecurityLevel(pPasswordStr) >= 70)
{
cout << "VERY_STRONG" << endl;
}
else if (GetPwdSecurityLevel(pPasswordStr) >= 60)
{
cout << "STRONG" << endl;
}
else if (GetPwdSecurityLevel(pPasswordStr) >= 50)
{
cout << "AVERAGE" << endl;
}
else if (GetPwdSecurityLevel(pPasswordStr) >= 25)
{
cout << "WEAK" << endl;
}
else if (GetPwdSecurityLevel(pPasswordStr) >= 0)
{
cout << "VERY_WEAK" << endl;
}
}
system("pause");
return 0;
}