力扣寒假刷题笔记(13)2.6

一、每日一题

 排序+双指针写法,先把Nums由小到大排序,然后遍历数组,选取大小相同的【i,j),如果长度为1就累加。

class Solution {
public:
    int sumOfUnique(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(),nums.end());
        int ans=0,i=0;
        while(i<n)
        {
            int j = i;
            while(j < n && nums[i] == nums[j])
            {
                j++;
            }
            if(j-i == 1) ans+=nums[i];
            i = j;
        }
        return ans;
    }
};

二、递归与递推

class Solution {
public:
    int addDigits(int num) {
        if(num<10) return num;
        int ans = 0;
        while(num)
        {
            ans += num%10;
            num /=10;
        }
        return addDigits(ans);
    }
};

这题基本思路是,枚举对第一行的所有操作,之后如果想要把整个方格全部点亮,就必须点亮这一行未点亮的对应的下一行方格,因为不能再对这一行进行操作。

对于第一行的每个操作,用二进制表示,0表示不做操作,1表示操作(熄灭或者点亮),那么所有操作就只有32种,循环0-32就行了。

#include <iostream>
#include <cstring>
using namespace std;
const int N=6;
char g[N][N],backup[N][N];
int dirx[]={-1,0,1,0,0},diry[] = {0,1,0,-1,0};
void turn(int x,int y)
{
    for(int i=0;i<5;i++)
    {
        int a= x+dirx[i],b=y+diry[i];
        if(a<0||a>=5||b<0||b>=5) continue;
        g[a][b] ^=1;
    }
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        for(int i=0;i<5;i++) cin>>g[i];
        int res=10;
        for(int op=0;op<32;op++)
        {
            memcpy(backup,g,sizeof g);
            int step = 0;
            for(int i=0;i<5;i++)
            {
                if(op>>i&1)
                {
                    step++;
                    turn(0,i);
                }
            }
            for(int i=0;i<4;i++)
            {
                for(int j=0;j<5;j++)
                {
                    if(g[i][j]=='0')
                    {
                        step++;
                        turn(i+1,j);
                    }
                }
            }
            bool dark=false;
            for(int i=0;i<5;i++)
            {
                if(g[4][i]=='0') {
                    dark = true;
                    break;
                }
            }
            if(!dark) res = min(res,step);
            memcpy(g,backup,sizeof backup);
        }
        if(res > 6) res = -1;
        cout<<res;
        puts("");
    }
}

 

 和上面那个题差不多,dfs暴力解决。

#include <iostream>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
const int N=5;
char g[N][N];
vector<PII> ans,tmp;
void turn_one(int x, int y)
{
    if (g[x][y] == '+') g[x][y] = '-';
    else g[x][y] = '+';
}

void turn_all(int x, int y)
{
    for (int i = 0; i < 4; i++)
    {
        turn_one(x, i);
        turn_one(i, y);
    }
    turn_one(x, y);
}

void dfs(int x,int y)
{
    if (x == 3 && y == 4)
    {
        bool success = true;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j <4; j++)
                if (g[i][j] == '+')
                {    
                    success = false;
                    goto end;
                }
        end:
        if (success)
            if (ans.empty() || tmp.size() < ans.size())
                ans = tmp;
        return;
    }
    // 判断边界,如果y出界了就往下一行移动
    if (y == 4) x++, y = 0;

    // 操作把手(x, y)
    turn_all(x, y);
    tmp.push_back({ x, y });
    dfs(x, y + 1);
    // 恢复现场
    tmp.pop_back();
    turn_all(x, y);

    // 不操作把手(x, y)
    dfs(x, y + 1);
}
int main()
{
    for(int i=0;i<4;i++)
    {
        cin>>g[i];
    }
    dfs(0,0);
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++)
    {
        cout<<ans[i].first + 1<<' '<<ans[i].second + 1<<endl;
    }
}

 只在一维方向进行操作。从左到右对比拿到的字符串p和标准串q,遇到p[i]和q[i]不同就改变i和i+1两处。

#include <iostream>
using namespace std;
const int N=110;
string g,q;
int main()
{
    cin>>g>>q;
    int n=g.size();
    int step=0;
    for(int i=0;i<n-1;i++)
    {
        if(q[i] != g[i])
        {
            step++;
            if(g[i] =='*') g[i] = 'o';
            else g[i] = '*';
            if(g[i+1] =='*') g[i+1] = 'o';
            else g[i+1] = '*';
        }
    }
    cout<<step;
}

 三、写递归题的时候遇到一个位运算的题目,还没有系统进行位运算学习就先列在这里。

class Solution {
public:
    bool isPowerOfTwo(int n) {
        return n > 0 && (n & -n) == n;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值