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;  
}