一、每日一题
排序+双指针写法,先把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;
}
};