目录
1. 代价
你有3个需要完成的任务,完成这3个任务是需要付出代价的。
首先,你可以不花任何代价的完成一个任务;然后,在完成了第i个任务之后,你可以花费|Ai - Aj|的代价完成第j个任务。|x|代表x的绝对值。
计算出完成所有任务的最小代价。
输入描述:
一行3个整数A1,A2,A3,每个数字之间用一个空格分隔。所有数字都是整数,并且在[1,100]范围内。
输出描述:
一个整数,代表最小的代价。
输入例子1:
1 6 3
输出例子1:
5
输入例子2:
10 10 10
输出例子2:
0
思路:将数据排序,从最后一个开始,依次往前,累加当前任务和前一个的差即可。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> data;
int tmp, res = 0;
for (size_t i = 0; i < 3; i++)
{
cin>>tmp;
data.push_back(tmp);
}
sort(data.begin(),data.end()); //排序
for (size_t i = data.size()-1; i >0; i--)
{
res += data[i] - data[i-1]; //从后往前依次累加差
}
cout<<res<<endl;
return 0;
}
2. 访友
小易准备去拜访他的朋友,他的家在0点,但是他的朋友的家在x点(x > 0),均在一条坐标轴上。小易每一次可以向前走1,2,3,4或者5步。问小易最少走多少次可以到达他的朋友的家。
输入描述:
一行包含一个数字x(1 <= x <= 1000000),代表朋友家的位置。
输出描述:
一个整数,最少的步数。
输入例子1:
4
输出例子1:
1
输入例子2:
10
输出例子2:
2
思路一:一直往前走,每一步都迈最大的步子
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int tmp, res = 0;
int cur = 0, next = 0, jump = 0;
int des;
cin>>des;
for (int i = 0; i <= des; i++)
{
if (cur<i) //还没有到达终点,最后一次是从des-1的地方开始走
{
jump++; //向前走一步
cur = next; //将从i-1能到达的最远的地方给cur
}
next = max(next, i+5); //从i出发能到达的最远的地方
}
cout<<jump<<endl;
return 0;
}
思路二:简单求解,每一次都走5步,最后不够5步的加一次就好,只能针对这种特殊情况才能用。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int tmp, res = 0;
int cur = 0, next = 0, jump = 0;
int des;
cin>>des;
if (des%5 > 0)
{
jump = des/5+1;
}else
{
jump = des/5;
}
cout<<jump<<endl;
return 0;
}
3. 翻转翻转
给定一个N*M的矩阵,在矩阵中每一块有一张牌,我们假定刚开始的时候所有牌的牌面向上。
现在对于每个块进行如下操作:
> 翻转某个块中的牌,并且与之相邻的其余八张牌也会被翻转。
XXX
XXX
XXX
如上矩阵所示,翻转中间那块时,这九块中的牌都会被翻转一次。
请输出在对矩阵中每一块进行如上操作以后,牌面向下的块的个数。
输入描述:
输入的第一行为测试用例数t(1 <= t <= 100000), 接下来t行,每行包含两个整数N,M(1 <= N, M <= 1,000,000,000)
输出描述:
对于每个用例输出包含一行,输出牌面向下的块的个数
输入例子1:
5 1 1 1 2 3 1 4 1 2 2
输出例子1:
1 0 1 2 0
思路一:分三种情况
1. 一行一列的只能翻一次,返回1
2. 1*m或n*1的情况一种,两头牌翻两次不变,中间的牌翻三次,向上变为向下,总的牌数减2即为结果
3. m*n的情况,4个角的牌被翻4次不变,4个边上除了角上的牌,会被翻6次也不变,中间的牌会被翻9次,向上变为向下,所以只要统计中间的牌有多少张就好,注意测试数据很大,需要用long long类型。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
long long num, N, M;
vector<vector<long long>> data, data1;
vector<long long> data_tmp, result;
long long tmp, res = 0;
cin>>num;
for (int i=0;i<num;i++) //读数据
{
cin>>N>>M;
data_tmp.push_back(N);
data_tmp.push_back(M);
data.push_back(data_tmp);
data_tmp.clear();
}
for (int i=0;i<num;i++)
{
if (data[i][0] == 1 && data[i][1] == 1) //1*1
{
result.push_back(1);
}else if(data[i][0] == 1 || data[i][1] == 1){ //1*m或n*1
result.push_back(max(data[i][0], data[i][1]) - 2);
}else{ //m*n
result.push_back((data[i][0] - 2) * (data[i][1] - 2));
}
}
for (int i=0;i<result.size();i++)
{
cout<<result[i]<<endl;
}
//cout<<result<<endl;
return 0;
}
思路二:对每一张牌按照题目要求进行翻牌操作,在这里为了避免最外一层的牌需要判断边界的问题,在最开始的时候在最外层加一层牌,这样就避免了边界判断的问题。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int num, N, M;
vector<vector<int>> data, data1;
vector<int> data_tmp, result;
int tmp, res = 0;
cin>>num;
for (int i=0;i<num;i++) //读数据
{
cin>>N>>M;
data_tmp.push_back(N);
data_tmp.push_back(M);
data.push_back(data_tmp);
data_tmp.clear();
}
for (int i=0;i<num;i++)
{
for (int j=0;j<data[i][1]+2;j++) //在最外层加上边界
{
data_tmp.push_back(0);
}
data1.push_back(data_tmp);
data_tmp.clear();
for (int j=0;j<data[i][0];j++)
{
data_tmp.push_back(0);
for (int p=0;p<data[i][1];p++)
{
data_tmp.push_back(0);
}
data_tmp.push_back(0);
data1.push_back(data_tmp);
data_tmp.clear();
}
for (int j=0;j<data[i][1]+2;j++)
{
data_tmp.push_back(0);
}
data1.push_back(data_tmp);
data_tmp.clear();
for (int m=1; m<data[i][0]+1; m++) //对每一张牌进行翻牌操作
{
for (int n=1; n<data[i][1]+1; n++)
{
for (int p=-1;p<=1;p++)
{
for (int q=-1;q<=1;q++)
{
if (data1[m+p][n+q] == 0)
{
data1[m+p][n+q] = 1;
}else{
data1[m+p][n+q] = 0;
}
}
}
}
}
for (int m=1; m<data[i][0]+1; m++) //统计朝下的牌
{
for (int n=1; n<data[i][1]+1; n++)
{
if (data1[m][n] == 1)
{
res += 1;
}
}
}
result.push_back(res);
res = 0;
data1.clear();
}
for (int i=0;i<result.size();i++)
{
cout<<result[i]<<endl;
}
//cout<<result<<endl;
return 0;
}
本文探讨了三个算法问题:计算完成任务的最小代价、寻找到达目标位置的最少步数,以及翻转矩阵中牌面后的状态计数。通过具体示例和代码实现,展示了如何使用排序、动态规划和数学分析来解决这些挑战。
&spm=1001.2101.3001.5002&articleId=93890571&d=1&t=3&u=01bcfabed77447b6b7c7caf563b39045)
509

被折叠的 条评论
为什么被折叠?



