- 高镜铠 的博客
7.11
- @ 2024-7-11 20:35:40
TP1 小田的四则运算
思路:计算每一种方案,用一个变量来计算最大值。
代码:
long long n=(a+b)*c
long long m=(a+c)*b;
long long x=(c+b)*a;
long long y=a+b+c;
long long q=a*b*c;
long long w=a+b*c;
long long z=b+a*c;
long long i=c+a*b;
maxn=max(maxn,n);
maxn=max(maxn,m);
maxn=max(maxn,x);
maxn=max(maxn,y);
maxn=max(maxn,q);
maxn=max(maxn,w);
maxn=max(maxn,z);
maxn=max(maxn,i);
样例: 1 2 3 计算得知最大的是:(1+2)*3=9
2 2 3 计算得知最大的是:2×2×3=12
TP2 小田的gcd构造
思路:寻找一个通用点,是所有点它都能满足。 取最大的n=5e18/z(向下取整)*z,m=z,就是这个通用情况,只需要输入之后将这个通用情况输出就行了。
样例: 这一题的样例与答案并无关系,纯纯干扰项,没有什么用。
TP3 小田的山峰数组
思路:循环枚举i,通过i来找第一个满足条件的j,找到之后,ans+=n - j,最后将ans输出。
样例: 5 1 2 3 4 5 第一组可行的为 i=1,j=4,第二组可行的为 i=2,j=4 。
4 3 1 2 4 因为1+2<4&&1+2=3 所以不满足条件,输出0。
TP4 Dota2参议院
思路:用两个队列来模拟,一开始先比较两个队列的队头,那个队头小就先让那个队头禁别人,禁完之后就把他放在队尾,再加上一个n,被禁了的那个人就直接将他弹出队列就行了。 样例: 2 RD RDD 对于RD: 第 1 轮时,第一个参议员来自 Radiant 阵营,他可以使用第一项权利让第二个参议员失去所有权利。 这一轮中,第二个参议员将会被跳过,因为他的权利被禁止了。 第 2 轮时,第一个参议员可以宣布胜利,因为他是唯一一个有投票权的人
TP5 小W走迷宫
思路:这一题用搜索来写,无论是深搜还是广搜都可以过。 样例: 6 6 .*.#.. .#.... ..##.. ...... .#.... ....@. 6 6 输出8。 代码:
#include<bits/stdc++.h>
using namespace std;
char mp[110][110];
int dis[110][110];
int n,m,sx,sy,ex,ey;
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
void dfs(int x,int y,int d){
dis[x][y]=d;
for(int i=0;i<=3;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>0&&ny>0&&nx<=m&&ny<=n&&mp[nx][ny]=='.'&&d+1<dis[nx][ny]){
dfs(nx,ny,d+1);
}
}
}
int main(){
memset(dis,0x3f,sizeof (dis));
cin>>m>>n;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>mp[i][j];
if(mp[i][j]=='@'){
sx=i,sy=j;
}
if(mp[i][j]=='*'){
ex=i,ey=j;
mp[i][j]='.';
}
}
}
dfs(sx,sy,0);
if(dis[ex][ey]==0x3f3f3f3f)cout<<"-1";
else cout<<dis[ex][ey];
return 0;
}
TP6
思路:图论模版 模版:贝尔曼-福特:
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(d[i][j]>d[i][k]+d[k][j])
d[i][j]=d[i][k]+d[k][j];
另一个:
#include <bits/stdc++.h>
using namespace std;
int arr[1005][1005];//邻接矩阵存储每条边
int dist[1005];//i的最短路长度
bool v[1005];//标记数组
int n, m, ans;
int dijkstra() {
memset(dist, 0x3f, sizeof(dist));//dist数组初始化最大
memset(v, 0, sizeof(v));//节点标记
dist[1] = 0; //节点1
for (int i = 1; i < n; i++) { //重复进行n-1次 ,还有n-1个点需要标记
int x = -1; //寻找未标记中 dist值最小的
for (int j = 1 ; j <= n ; j++) {
if (!v[j] && (x == -1 || dist[j] < dist[x])) x = j; //未标记且最小
}
v[x] = 1; //找到后标记该节点
for (int y = 1; y <= n; y++) { //用当前最小值x更新其他节点
dist[y] = min(dist[y], dist[x] + arr[x][y]); //更新最短路
}
}
if (dist[n] == 0x3f3f3f3f) return -1; //未更新输出-1
return dist[n];
}
int main() {
scanf("%d%d", &n, &m);
//构建邻接矩阵
memset(arr, 0x3f, sizeof(arr)); //极大
for (int i = 1; i <= n; i++) arr[i][i] = 0;
for (int i = 1; i <= m; i++) { //存边
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
arr[x][y] = min(arr[x][y], z); //有重边只保留最小边
}
ans = dijkstra();
printf("%d\n", ans);
return 0;
}