年终奖
此题是一道动态规划的问题
读题可知:只能从上往下和从左往右移动
由此需要前[i-1] [ j ]和[i][j-1]来比较大小来确实最优解。
其中有两种特殊情况,第一行和第一列
代码如下:
class Bonus {
public:
int getMost(vector<vector<int> > board) {
int Row=board.size();
int Col=board.size();
vector<vector<int>> Price(Row,vector<int> (Col,0));
Price[0][0]=board[0][0];
for(int i=0;i<Row;i++)
{
for(int j=0;j<Col;j++)
{
if(i==0&&j==0)
continue;
else if(i==0)
Price[i][j]=Price[i][j-1]+board[i][j];
else if(j==0)
Price[i][j]=Price[i-1][j]+board[i][j];
else
Price[i][j]=max(Price[i][j-1],Price[i-1][j])+board[i][j];
}
}
return Price[Row-1][Col-1];
}
};
微信红包
此题题意简单,看到有超过一半的数,我们可以想到两种方法。
方法一:先排序,统计中间那个数的出现次数,如果大于数组大小的一半就输出
方法二:使用map
代码如下:
方法一
class Gift {
public:
int getValue(vector<int> gifts, int n) {
sort(gifts.begin(),gifts.end());
int mid_val=gifts[n/2];
int count=0;
for(const auto& e:gifts)
{
if(e==mid_val)
count++;
}
if(count>n/2)
return mid_val;
else
return 0;
}
};
方法二
class Gift {
public:
int getValue(vector<int> gifts, int n) {
map<int,int> val_count_map;
for(const auto& e:gifts)
{
val_count_map[e]++;
}
for(const auto& e:val_count_map)
{
if(e.second>n/2)
return e.first;
}
return 0;
}
};
找出字符串中第一个只出现一次的字符
此题比较简单,有三种方法
暴力法:
双层循环遍历,当第二层循环遍历找到相同值时,退出当前j循环,当第二次循环完了,还没找到就返回当前str[i]
哈希法:
统计字符次数,找出第一个次数为1的字符即可
string 类函数法
利用find函数,一个从前查找,一个从后查找,当找到的是同一个值时,返回当前值
代码如下:
#include <iostream>
#include<string>
using namespace std;
char FirstOneChar1(const string& str)
{
int j;
for(int i=0;i<str.size();i++)
{
for(j=0;j<str.size();j++)
{
if(j==i)
continue;
if(str[j]==str[i])
break;
}
if(j>=str.size())
return str[i];
}
return -1;
}
char FirstOneChar2(const string& str)
{
int hash[128]={0};
for(int i=0;i<str.size();i++)
{
hash[str[i]]++;
}
for(int i=0;i<str.size();i++)
{
if(hash[str[i]]==1)
return str[i];
}
return -1;
}
char FirstOnechar3(const string& str)
{
for(int i=0;i<str.size();i++)
{
int index1=str.find(str[i]);
int index2=str.rfind(str[i]);
if(index1==index2)
return str[i];
}
return -1;
}
int main()
{
string str;
char res;
while(getline(cin,str))
{
res=FirstOneChar3(str);
if(res==-1)
cout<<-1<<endl;
else
cout<<res<<endl;
}
return 0;
}
洗牌
解题思路如下:
找出左右手规律即可
注意输出格式
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int t,n,k;
cin>>t;//组数
while(t--)
{
cin>>n>>k;
int num=2*n;
vector<int> card(num);
for(int i=0;i<num;i++)//控制反转次数
cin>>card[i];
for(int i=0;i<k;i++)
{
vector<int> tmp(card.begin(),card.end());//复制数组
for(int j=0;j<n;j++)
{
card[2*j]=tmp[j];
card[2*j+1]=tmp[j+n];
}
}
for(int i=0;i<num-1;i++)
cout<<card[i]<<" ";//注意最后一个空格不能输出
cout<<card[num-1]<<endl;
}
return 0;
}