2006Problem - 2006 (hdu.edu.cn)
#include <iostream>
using namespace std;
int main()
{
int n ,x;
while(cin >> n)
{
int ret =1;
for(int i = 0;i < n ;i++)
{
cin >> x;
if(x %2 != 0)
{
ret *= x;
}
}
cout << ret << endl;
}
return 0;
}
2008Problem - 2008 (hdu.edu.cn)
知识点:对于0的精度处理 --- 使用 esp宏定义 1e-8(即1的负八次方)来代替
<-esp 表示负数
<esp 表示0
>esp 表示正数
#include <iostream>
#include <cmath>
#define esp 1e-8
using namespace std;
int main()
{
int n;
while(cin >> n && n)//n为0时不做任何处理
{
double x;
int a =0,b=0,c=0;
for(int i = 0;i<n;i++)
{
cin >>x;
if(x < -esp)
{
a++;
}
else if(fabs(x) < esp) //不能直接用x==0,因为有精度误差;但是其实用了,也能通过编译
{
b++;
}
else if(x > esp)
{
c++;
}
}
cout << a <<' '<<b<<' '<<c<<' '<<endl;
}
return 0;
}
2014Problem - 2014 (hdu.edu.cn)
知识点:双精度浮点数、输入多组数据、输出浮点数 、保留小数点后两位
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n,max,min;
while(cin>>n)
{
double sum = 0;
int tmp = n-2;
max = -1000000;
min = 1000000;
while(n--)
{
int x;
cin >> x;
if( x>max)
{
max =x;
}
if(x < min)
{
min = x;
}
sum += x;
}
sum = (sum - min-max)*1.0/tmp;
printf("%.2lf\n",sum);
}
return 0;
}
LCP 01. 猜数字
方法1
知识点:计算数组的长度 guess.size()、遍历
class Solution {
public:
int game(vector<int>& guess, vector<int>& answer) {
int count =0;
for(int i =0; i< guess.size() ;i++){
if(guess[i] == answer[i]){
count++;
}
}
return count;
}
};
方法2
class Solution {
public:
int game(vector<int>& guess, vector<int>& answer) {
return (guess[0] == answer[0]) + (guess[1] == answer[1]) + (guess[2] == answer[2]) ;
}
};
LCP 06. 拿硬币
知识点:计数的拿硬币模型,不够偶数时要多拿一次
计算公式 (n+1)/2 ---- n为每堆个数
class Solution {
public:
int minCount(vector<int>& coins) {
int ret =0;
for(int i = 0;i<coins.size();i++){
ret += (coins[i]+1)/2;
}
return ret;
}
};
2057. 值相等的最小索引
知识点: 从小到大遍历,遇到的第一个符合条件的就是最小的
class Solution {
public:
int smallestEqual(vector<int>& nums) {
for(int i =0;i< nums.size();i++)
{
if(i % 10 == nums[i])
{
return i;
}
}
return -1;
}
};
485. 最大连续 1 的个数 - 力扣(LeetCode)
知识点:边界的处理
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int count =0,maxcount = 0;
for(int i = 0;i<nums.size() ;i++)
{
if(nums[i] == 1)
{
count++;
}
else
{
maxcount = fmax(count,maxcount);
count = 0;
}
}
maxcount = fmax(count,maxcount);
return maxcount;
}
};
2006. 差的绝对值为 K 的数对数目
class Solution {
public:
int countKDifference(vector<int>& nums, int k) {
int cnt =0;
for(int i =0;i<nums.size();i++){
for(int j = i+1;j<nums.size();j++)
{
if(abs(nums[i] - nums[j]) == k){
cnt++;
}
}
}
return cnt;
}
};
1464. 数组中两元素的最大乘积
知识点:贪心
class Solution {
public:
int maxProduct(vector<int>& nums) {
//贪心
sort(nums.begin(),nums.end());
return (nums[nums.size()-1]-1)*(nums[nums.size()-2]-1);
}
};
2656. K 个元素的最大和
知识点:贪心
class Solution {
public:
int maximizeSum(vector<int>& nums, int k) {
//贪心
int m = *max_element(nums.begin(),nums.end());//取最大值
return ((2*m + k-1)*k)/2; //等差数列求和
}
};
2367. 算术三元组的数目
知识点:同向双指针(数组严格升序,不会漏情况)
class Solution {
public:
int arithmeticTriplets(vector<int>& nums, int diff) {
int ans =0, i = 0,j = 1;
for(int x:nums)//遍历数组
{
while(nums[j]+diff < x)
{
j++;
}
if(nums[j]+diff > x) continue;//x定为三元中最大的值,所以这种情况直接跳过
while(nums[i] + 2*diff < x)
{
i++;
}
if(nums[i] + 2*diff == x)//能到这一步说明j已经符合要求
ans++;
}
return ans;
}
};
为什么要加上差值呢?这是因为我们在寻找等差数列时,需要找到满足以下条件的三个数:第二个数减去第一个数等于diff
,第三个数减去第二个数也等于diff
。换句话说,我们需要找到这样的三个数:nums[i]
,nums[j]
和x
,使得nums[j] - nums[i] = diff
和x - nums[j] = diff
。
在代码中,我们通过增加j
和i
的值来寻找满足这些条件的数。当nums[j] + diff < x
时,我们增加j
的值;当nums[i] + diff * 2 < x
时,我们增加i
的值。这样,我们就可以在数组中找到所有满足条件的等差数列,并用ans
来记录找到的数量。
解法二:哈希表
class Solution {
public:
int arithmeticTriplets(vector<int> &nums, int diff) {
int ans = 0; // 初始化计数器
unordered_set<int> s{nums.begin(), nums.end()}; // 创建一个集合,包含nums中的所有元素
for (int x: nums) { // 遍历数组nums,x为当前元素
if (s.count(x - diff) && s.count(x + diff)) // 如果集合中存在x-diff和x+diff
++ans; // 计数器加一
}
return ans; // 返回计数器的值
}
};
1929. 数组串联
易错点:
nums.size()不能放进循环判断条件中,因为nums数组每一次都在增长,所以在每一次循环时nums.size()都在变大,所以看起来把n替换成nums.size()是一样的,其实不是。这里的n提前保存了数组长度,确保数组正确串联。
class Solution {
public:
vector<int> getConcatenation(vector<int>& nums) {
int n = nums.size();
for(int i =0;i<n;i++)
{
nums.push_back(nums[i]);
}
return nums;
}
};
27. 移除元素
知识点:双指针
方法一
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size();
int left = 0;
for(int right = 0; right < n; right++)
{
if(nums[right] != val)
{
nums[left++] = nums[right];
}
}
return left;
}
};
妙妙妙啊
方法二
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//双指针
//left 左边的值是不等于val的,右边值是等于val的
int right = nums.size()-1,left = 0;
for(left = 0; left <= right;left++)
{
if(nums[left] == val)
{
swap(nums[left--],nums[right--]);//换给left的应该是非val值
}
}
return left;
}
};
1920. 基于排列构建数组
易错:
class Solution {
public:
vector<int> buildArray(vector<int>& nums) {
vector<int>ans;
for(int i = 0;i<nums.size();i++)
{
ans.push_back(nums[nums[i]]);
}
return ans;
}
};
空间复杂度为O(1)的方法
因为原题目限制数组元素的大小最大为1000,而要让一个元素同时拥有原来的元素值和需要改变的元素值,就通过设置一个密码来实现(相当于先加密再解密,解密的时候用不同的方式能够实现得到原始值或者改变值)
因为元素大小小于等于1000,所以%1000,元素大小不会改变,但是却可以让被加密的元素变回原来的值;而这个加密其实就是在原始值上 + 需要改变值*1000
所以第一遍for循环就是实现所有数的加密
第二遍for循环解密
直接/1000 ; 因为原先加密是用了改变值*1000,这里除了之后得到的就是改变值;原本的原始值因为大小不够1000而被自动舍弃(利用了 / 的特性)
class Solution {
public:
vector<int> buildArray(vector<int>& nums) {
int n = nums.size();
// 第一次遍历编码最终值
for (int i = 0; i < n; ++i){
// 将 nums[nums[i]] 的值编码到 nums[i] 中,同时保留 nums[i] 的原始值
nums[i] += 1000 * (nums[nums[i]] % 1000);
}
// 第二次遍历修改为最终值
for (int i = 0; i < n; ++i){
// 将 nums[i] 的值修改为最终值
nums[i] /= 1000;
}
return nums;
}
};
1431. 拥有最多糖果的孩子
class Solution {
public:
vector<bool> kidsWithCandies(vector<int>& candies, int extraCandies) {
int max = INT_MIN;
for(int i = 0;i<candies.size();i++)
{
if(candies[i] > max)
{
max = candies[i];
}
}
vector<bool>ans;
for(int i = 0;i< candies.size();i++ )
{
if(candies[i]+extraCandies >= max)
{
ans.push_back(true);
}
else
{
ans.push_back(false) ;
}
}
return ans;
}
};