杂题
dfs:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int N = 205;
int n, a, b,ans = 0x3f3f3f3f,flag;
int k[N];
bool vis[N];
void dfs(int x, int cnt)
{
if(ans < cnt)return;
if(x == b)
{
flag = true;
ans = min(ans, cnt);
return;
}
if(x + k[x] <= n && (!vis[x+k[x]]))
{
vis[x+k[x]] = true;
dfs(x+k[x], cnt+1);
vis[x+k[x]] = false;
}
if(x - k[x] > 0 && (!vis[x-k[x]]))
{
vis[x-k[x]] = true;
dfs(x-k[x], cnt+1);
vis[x-k[x]] = false;
}
return;
}
int main()
{
scanf("%d%d%d",&n, &a, &b);
for(int i = 1; i <= n; i++)scanf("%d", &k[i]);
dfs(a,0);
if(flag)printf("%d\n", ans);
else printf("-1\n");
return 0;
}
bfs :
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 205;
int k[N], n, a, b;
bool vis[N];
int bfs(int a, int b)
{
queue<PII>q;
q.push({a, 0});
while(q.size())
{
PII t = q.front();
q.pop();
if(t.first == b)return t.second;
if(t.first + k[t.first] <= n && !vis[t.first + k[t.first]])
{
q.push({t.first + k[t.first], t.second + 1});
vis[t.first + k[t.first]] = true;
}
if(t.first - k[t.first] > 0 && !vis[t.first - k[t.first]])
{
q.push({t.first - k[t.first], t.second + 1});
vis[t.first - k[t.first]] = true;
}
}
return -1;
}
int main()
{
scanf("%d%d%d",&n, &a, &b);
for(int i = 1;i <= n; i++)scanf("%d", &k[i]);
int ans = bfs(a, b);
printf("%d", ans);
return 0;
}
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int N = 100005;
bool vis[N];
int n, k, ans;
struct node{
int x, t;
};
queue<node>q;
void bfs()
{
vis[n] = true;
vis[0] = true;//易错点,vis[0]一定要标记
node now = (node){n, 0};
q.push(now);
while(q.size())
{
now = q.front();
q.pop();
if(now.x == k)
{
printf("%d\n", now.t);
break;
}
if(!vis[now.x+1])
{
vis[now.x+1] = true;
q.push((node){now.x+1, now.t+1});
}
if(now.x-1 >= 0 && !vis[now.x-1])
{
vis[now.x-1] = true;
q.push((node){now.x-1, now.t+1});
}
if(now.x*2 <= 100010 && !vis[now.x*2])
{
vis[now.x*2] = true;
q.push((node){now.x*2, now.t+1});
}
}
}
int main()
{
scanf("%d%d",&n, &k);
if(k < n)
{
printf("%d\n", n-k);
return 0;
}
bfs();
return 0;
}
3.棋盘问题
//注意边界问题,还有这一层棋子有不放的这种情况
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 10;
int n, k;
char m[N][N];
int vis[N];
int ans;
void dfs(int cal, int step)
{
if(step == k)
{
ans++;
return;
}
if(cal >= n)return;
for(int i = 0;i < n;i++)//摆所有列
{
if(m[cal][i] == '#' && !vis[i])
{
vis[i] = 1;
dfs(cal+1, step+1);
vis[i] = 0;
}
}
dfs(cal+1,step);//这一行不放棋子
return;
}
int main()
{
while(1)
{
ans = 0;
memset(vis, 0, sizeof vis);
scanf("%d%d", &n, &k);
if(n == -1)break;
for(int i = 0;i < n;i++)scanf("%s", m[i]);
dfs(0, 0);
printf("%d\n", ans);
}
return 0;
}
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 105;
int Map[N][N];
int d[N][N]; //记忆化搜索
int vis[N][N];
int m, n, ans;
int dx[] = {0, 0, 1, -1},dy[] = {1, -1, 0, 0};
void dfs(int x, int y, int flag, int sum)
{
if(sum >= d[x][y])return;//这是一个剪枝,记忆化
d[x][y] = sum;
if(x == m && y == m)
{
ans = min(ans, sum);
return;
}
for(int i = 0;i < 4;i++)
{
int xx = x+dx[i],yy = y+dy[i];
if(xx >= 1 && xx <= m && yy >= 1 && yy <= m && !vis[xx][yy])
{
vis[xx][yy] = 1;
if(Map[xx][yy] == -1)
{
if(!flag)
{
Map[xx][yy] = Map[x][y];
dfs(xx, yy, 1, sum+2);
Map[xx][yy] = -1;
}
}
else
{
if(Map[xx][yy] == Map[x][y])dfs(xx, yy, 0, sum);
else dfs(xx, yy, 0, sum+1);
}
vis[xx][yy] = 0;//注意回复现场
}
}
return;
}
int main()
{
scanf("%d%d",&m, &n);
memset(Map,-1,sizeof Map);
memset(d,0x3f3f3f3f, sizeof d);
for(int i = 1;i <= n;i++)
{
int x, y, c;
scanf("%d%d%d",&x, &y, &c);
Map[x][y] = c;
}
ans = 0x3f3f3f3f;
dfs(1, 1, 0, 0);
if(ans == 0x3f3f3f3f)printf("-1\n");
else printf("%d\n",ans);
return 0;
}
最强对手矩阵
- 不能使用全局变量const int N = 100010;这样会爆内存,使用vector用多少存多少。
- o(n^2m)只能过70%样例,过100%样例可以通过矩阵旋转的方法,降低复杂度。
- vector的反转和普通整型矩阵不同,要注意反转的细节。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,m,res = -0x3f3f3f3f;
scanf("%d%d",&n,&m);
vector<vector<int>>g(n+1,vector<int>(m+1));
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
scanf("%d",&g[i][j]);
if(n < m)
{
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
g[i][j]+=g[i-1][j];
for(int i = 1;i <= n;i++)
for(int j = i;j <= n;j++)
{
int last = 0;
for(int k = 1;k <= m;k++)
{
last = max(last,0)+g[j][k]-g[i-1][k];
res = max(res,last);
}
}
printf("%d\n",res);
}
else
{
vector<vector<int>>f(m+1,vector<int>(n+1));
for(int i = 1;i <= m;i++)
for(int j = 1;j <= n;j++)
f[i][j] = g[j][i];
swap(n, m);
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
{
f[i][j] += f[i-1][j];
}
for(int i = 1;i <= n;i++)
for(int j = i;j <= n;j++)
{
int last = 0;
for(int k = 1;k <= m;k++)
{
last = max(last,0)+f[j][k]-f[i-1][k];
res = max(res,last);
}
}
printf("%d\n",res);
}
return 0;
}
斐波那契
- 变成变化简,化简使用gcd,
- gcd实现的时候要用long long,int会出错
#include <bits/stdc++.h>
using namespace std;
int fun(int n)
{
if(n < 3)return 1;
else return fun(n-2)+fun(n-1);
}
long long gcd(long long a,long long b)
{
return b?gcd(b,a%b):a;
}
int main()
{
double ans = 0;
long long fenmu = 1,fenzi = 1;
for(int i = 3;i <= 14;i++)
{
if(i > 1)
{
fenzi = fenzi*(fun(i)*fun(i-1))+fenmu;
fenmu = fenmu*(fun(i)*fun(i-1));
int mod = gcd(fenzi,fenmu);
fenzi/=mod;fenmu/=mod;
}
}
printf("%lld/%lld\n",fenzi,fenmu);
}

浙公网安备 33010602011771号