这是一个标准代码的模板
#include<iostream>
using namespace std;
int main()
{
return 0;
}
下面有一些例题
1. P1001 A+B
题目描述
输入两个整数 a,b,输出它们的和(∣a∣,∣b∣≤10^9)。
输入格式
两个整数以空格分开。
输出格式
一个整数。
输入输出样例
输入 #1
1 2
输出 #1
3
代码
#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << a+b;
return 0;
}
2.P1002过河卒
题目描述
棋盘上 A 点有一个过河卒,需要走到目标 B* 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C* 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A* 点 (0,0)、B 点(n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 A* 点能够到达 B* 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 B* 点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
输入输出样例
输入 #1
6 6 3 3
输出 #1
6
说明/提示
对于 100% 的数据,1≤n,m≤20,0 ≤ 马的坐标 ≤20。
代码
// luogu-judger-enable-o2
#include<cstdio>
const int Const[2][9]={
{
0,-2,-1,1,2,2,1,-1,-2},{
0,1,2,2,1,-1,-2,-2,-1}};
long long DP[21][21]={
1};
bool mark[21][21];
int main() {
int nx,ny,hx,hy;
scanf("%d%d%d%d",&nx,&ny,&hx,&hy);
for(int i=0;i<9;++i)
if(hx+Const[0][i]>=0&&hx+Const[0][i]<=nx&&hy+Const[1][i]>=0&&hy+Const[1][i]<=ny)
mark[hx+Const[0][i]][hy+Const[1][i]]=1;
for(int i=0;i<=nx;++i)
for(int j=0;j<=ny;++j) {
if(i)
DP[i][j]+=DP[i-1][j];
if(j)
DP[i][j]+=DP[i][j-1];
DP[i][j]*=!mark[i][j];
}
printf("%lld",DP[nx][ny]);
return 0;
}
3.P1003铺地毯
题目描述
为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n 张地毯,编号从 1 到 n*。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。
输入格式
输入共 n*+2 行。
第一行,一个整数 n*,表示总共有 n* 张地毯。
接下来的 n* 行中,第 i+1 行表示编号 ii 的地毯的信息,包含四个整数 a*,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标 (a,b) 以及地毯在 x* 轴和 y 轴方向的长度。
第 n+2 行包含两个整数 x 和 y,表示所求的地面的点的坐标 (x, y)(x,y)。
输出格式
输出共 1 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出 -1
。
输入输出样例
输入 #1
3
1 0 2 3
0 2 3 3
2 1 3 3
2 2
输出 #1
3
输入 #2
3
1 0 2 3
0 2 3 3
2 1 3 3
4 5
输出 #2
-1
说明/提示
【样例解释 1】
如下图,1 号地毯用实线表示,2 号地毯用虚线表示,3 号用双实线表示,覆盖点 (2,2) 的最上面一张地毯是 3 号地毯。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int main()
{
int n;
cin>>n;
int a[n][4];
for(int i=0;i<n;i++)
{
cin>>a[i][0]>>a[i][1]>>a[i][2]>>a[i][3];
}
int x,y;
cin>>x>>y;
int sum=-1;
for(int i=0;i<n;i++)
{
if(x>=a[i][0]&&x<=a[i][0]+a[i][2]&&y>=a[i][1]&&y<=a[i][1]+a[i][3])
{
sum=i+1;
}
}
cout<<sum;
}
4.P1004 方格取数
题目描述
设有 N×N* 的方格图 (N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00。如下图所示(见样例):
A
0 0 0 0 0 0 0 0
0 0 13 0 0 6 0 0
0 0 0 0 7 0 0 0
0 0 0 14 0 0 0 0
0 21 0 0 0 4 0 0
0 0 15 0 0 0 0 0
0 14 0 0 0 0 0 0
0 0 0 0 0 0 0 0
B
某人从图的左上角的 A 点出发,可以向下行走,也可以向右走,直到到达右下角的 B 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字 0)。
此人从 A 点到 B 点共走两次,试找出 2 条这样的路径,使得取得的数之和为最大。
输入格式
输入的第一行为一个整数 N*(表示N×*N 的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的 0 表示输入结束。
输出格式
只需输出一个整数,表示 2 条路径上取得的最大的和。
输入输出样例
输入 #1
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
输出 #1
67
说明/提示
NOIP 2000 提高组第四题
代码
#include<cstdio>
#include<algorithm>
using namespace std;
struct point
{
int x,y,data;
}p[100];
int n,m,map[11][11],f[11][11][11][11];
int main()
{
int i,j,k,l;
scanf("%d",&n);
while(1)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(!a&&!b&&!c)
break;
p[++m].x=a;
p[m].y=b;
p[m].data=c;
}
for(i=1;i<=m;i++)
map[p[i].x][p[i].y]=p[i].data;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
for(k=1;k<=n;k++)
{
l=i+j-k;
if(l<=0)
break;
f[i][j][k][l]=max(f[i-1][j][k-1][l],max(f[i-1][j][k][l-1],max(f[i][j-1][k-1][l],f[i][j-1][k][l-1])));
if(i==k&&j==l)
f[i][j][k][l]+=map[i][j];
else
f[i][j][k][l]+=map[i][j]+map[k][l];
}
printf("%d\n",f[n][n][n][n]);
return 0;
}
5.P1005 矩阵取数游戏
题目描述
帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的 n×m 的矩阵,矩阵中的每个元素 a i,j 均为非负整数。游戏规则如下:
- 每次取数时须从每行各取走一个元素,共 n 个。经过 m 次后取完矩阵内所有元素;
- 每次取走的各个元素只能是该元素所在行的行首或行尾;
- 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值 \times 2i,其中i 表示第i次取数(从 1 开始编号);
- 游戏结束总得分为 m 次取数得分之和。
帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。
输入格式
输入文件包括 n+1 行:
第一行为两个用空格隔开的整数 n 和 m。
第 2∽n+1 行为 n×m 矩阵,其中每行有 m 个用单个空格隔开的非负整数。
输出格式
输出文件仅包含11行,为一个整数,即输入矩阵取数后的最大得分。
输入输出样例
输入 #1
2 3
1 2 3
3 4 2
输出 #1
82
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN = 85, Mod = 10000; //高精四位压缩大法好
int n, m;
int ar[MAXN];
struct HP {
int p[505], len;
HP() {
memset(p, 0, sizeof p);
len = 0;
} //这是构造函数,用于直接创建一个高精度变量
void print() {
printf("%d", p[len]);
for (int i = len - 1; i > 0; i--) {
if (p[i] == 0) {
printf("0000");
continue;
}
for (int k = 10; k * p[i] < Mod; k *= 10)
printf("0");
printf("%d", p[i]);
}
} //四位压缩的输出
} f[MAXN][MAXN], base[MAXN], ans;
HP operator + (const HP &a, const HP &b) {
HP c; c.len = max(a.len, b.len); int x = 0;
for (int i = 1; i <= c.len; i++) {
c.p[i] = a.p[i] + b.p[i] + x;
x = c.p[i] / Mod;
c.p[i] %= Mod;
}
if (x > 0)
c.p[++c.len] = x;
return c;
} //高精+高精
HP operator * (const HP &a, const int &b) {
HP c; c.len = a.len; int x = 0;
for (int i = 1; i <= c.len; i++) {
c.p[i] = a.p[i] * b + x;
x = c.p[i] / Mod;
c.p[i] %= Mod;
}
while (x > 0)
c.p[++c.len] = x % Mod, x /= Mod;
return c;
} //高精*单精
HP max(const HP &a, const HP &b) {
if (a.len > b.len)
return a;
else if (a.len < b.len)
return b;
for (int i = a.len; i > 0; i--)
if (a.p[i] > b.p[i])
return a;
else if (a.p[i] < b.p[i])
return b;
return a;
} //比较取最大值
void BaseTwo() {
base[0].p[1] = 1, base[0].len = 1;
for (int i = 1; i <= m + 2; i++){
//这里是m! m! m! 我TM写成n调了n年...
base[i] = base[i - 1] * 2;
}
} //预处理出2的幂
int main(void) {
scanf("%d%d", &n, &m);
BaseTwo();
while (n--) {
memset(f, 0, sizeof f);
for (int i = 1; i <= m; i++)
scanf("%d", &ar[i]);
for (int i = 1; i <= m; i++)
for (int j = m; j >= i; j--) {
//因为终值是小区间,DP自然就从大区间开始
f[i][j] = max(f[i][j], f[i - 1][j] + base[m - j + i - 1] * ar[i - 1]);
f[i][j] = max(f[i][j], f[i][j + 1] + base[m - j + i - 1] * ar[j + 1]);
} //用结构体重载运算符写起来比较自然
HP Max;
for (int i = 1; i <= m; i++)
Max = max(Max, f[i][i] + base[m] * ar[i]);
ans = ans + Max; //记录到总答案中
}
ans.print(); //输出
return 0;
}