我的编程之算法篇

1.洛谷P1006 [NOIP2008 提高组] 传纸条

        P1006 [NOIP2008 提高组] 传纸条 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

       思路分析:

        该题为经典的dp动态,除了起始点(1,1)和终点(n,m)纸条的来回传递位置不能重复,我们可以把该来回的过程看作是两个纸条从起始点到终点的过程。可以设置一个四位数组(F[r1][c2][r2][c2])来纪录两个点的位置。但是这样需要用四个循环,非常的费时间,可能会超时。所以我们改为三维数组(F[p][r1][r2])来记录,因为每时每刻两个纸条走的步数p相同。i, j分别表示他们处在的行数则他们的坐标分别为(i,p-i+1)   (j,p-j+1)。当i和j相等时即两点在同一位置(证明该点的值对上一步的两个纸条来说都比较大(如图))则点的值只能加一次。

我的编程之算法篇_第1张图片

 代码:

#include
#include
#include
using namespace std;

int f[110][60][60];
int a[60][60];

int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> a[i][j];
    f[1][1][1] = a[1][1];
    for (int p = 2; p <= n + m - 1; p++)
        for (int i = 1; i <= n && i <= p; i++)
            for (int j = 1; j <= n && j <= p; j++)
            {
                if (i == 1 && j == 1) continue;
                //找出上一步中的最大值
                f[p][i][j] = max(max(f[p - 1][i][j], f[p - 1][i - 1][j]), max(f[p - 1][i][j - 1], f[p - 1][i - 1][j - 1]));
                // 三目运算符  判断条件?true输出表达式1:false输出表达式2;然后求和
                //表达式1即为i和j相等,位置重复则只加一次
                f[p][i][j] += i == j ? a[i][p - i + 1] : a[i][p - i + 1] + a[j][p - j + 1];
            }
    printf("%d\n", f[n + m - 1][n][n]);
    return 0;
}

小知识点总结:

        三目运算符   判断条件?(true)输出表达式1:(false)输出表达式2;

2.洛谷 P1008 [NOIP1998 普及组]  三连击

P1008 [NOIP1998 普及组] 三连击 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

        题目分析:

        将1到9组成三个三位数并且是1比2比3的关系,怎么组怎么比毫无头绪,但是组成的这三个数(假设能重复)各自的范围是100~333:334~666:667~999;不重复则最小的三位数是123,最大的为987,于是我们就有一个大胆的想法,让三个数分别为a,b,c。则可以让a从123开始循环b=2*a;c=3*a;保证abc三个数只能用一次1~9则将百位十位个位分离验证。

        知识点:

        分离百十个位方法  设该数为n

        百位=n%100;

        十位=n/10%10;

        个位=n%10;

        代码:

#include
using namespace std;
int main()
{
	for (int a=123; a <= 333; a++)
	{
		int b, c;
		b = a * 2;
		c = a * 3;
		if ((a / 100 + a / 10 % 10 + a % 10 + b / 100 + b / 10 % 10 + b % 10 + c / 100 + c / 10 % 10 + c % 10 == 1+2+3+4+5+6+7+8+9)&&(   (a/100)*(a/10%10)*(a%10)*(b/100)*(b/10%10)*(b%10)*(c/100)*(c/10%10)*(c%10)==1*2*3*4*5*6*7*8*9  )  )
			cout << a <<"  " << b << "  " << c << endl;
		
	}
	return 0;
}

你可能感兴趣的:(我的编程之算法题解,算法,数据结构,c++)