洛谷P4431
题意翻译
题目大意:
给定一个n*mn∗m的矩阵,每次你可以选择前进一格或转弯(90度),求在不出这个矩阵的情况下遍历全部格点所需最少转弯次数。有多组数据
输入格式:
第一行一个整数kk,表示数据组数
以下kk行,每行两个整数n,mn,m,表示矩阵大小
输出格式:
输出一个整数,即最少转弯次数
感谢@守望 提供翻译
题目描述
mirko wants to buy land on which he will build a house for his family. so far, he’s seen k pieces of land. each of them is in the shape of a rectangle and we can think of it as a matrix with n rows and m columns, n × m fields in total.
mirko is aware that, before construction begins, the property needs to be regularly maintained and the lawn needs to be mowed. because of this, mirko bought a lawn mower. in order to mow the entire lawn of n rows and m columns, he needs to go over each field at least once. he can start from any field facing one of the four main directions (up, down, left, and right). his lawn mower can only go forwards (to the adjacent field facing the current direction) or make a 90 degree turn. additionally, because of his own safety, mirko can only use the lawn mower on his land, so he cannot leave the matrix.
since making the lawn mower turn isn’t simple, mirko wants to mow the lawn with the minimal amount of turns. for each piece of land he saw so far, mirko wants to know the minimal number of turns he can make so that the entire lawn is mowed. help mirko solve this problem.
输入输出格式
输入格式:
the first line of input contains the positive integer k (1 ≤ k ≤ 50 000), the number from the task.
each of the following k lines contains two positive integers n and m (1 ≤ n, m ≤ 1 000 000), the numbers from the task.
输出格式:
for each piece of land mirko saw so far, output in a separate line the minimal amount of turns he can take so that the entire lawn is mowed.
输入输出样例
说明
in test cases worth 50% of total points, mirko will see only one piece of land. the dimensions of this piece of land will be smaller than 500.
clarification of the first test case:
the first piece of land can be mowed without making any turns if he starts from the field in the first column of the table, faced to the right and only going forwards. a similar idea applies for the second piece of land.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
int a,b;
cin>>a>>b;
if(a==1||b==1)
{
cout<<0<<endl;
continue;
}
else
{
int js=1;
int total=0;
if(a>b)
{
while(a!=0&&b!=0)
{
if(js%2==0) a--;
else b--;
total++;
js++;
}
}
else
{
while(a!=0&&b!=0)
{
if(js%2==0) b--;
else a--;
total++;
js++;
}
}
cout<<total-1<<endl;
}
}
return 0;
}
因为没有障碍并且求最少转弯次数所以一次走完一整行或一整列就是最优解法。。。所以可以模拟为给行数或列数减一。。。
然后分析一下,画个图看一下发现当行数大于列数时先走一整行(即先给行数减一再给列数减一直至有一数为零)当行数小与列数时先走一整列(即先给列数减一再给行数减一直至有一数为零)。但上面这个代码会tle!!
当我尝试着改成如下代码时,还是tle!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
int a,b;
cin>>a>>b;
if(a==1||b==1)
{
cout<<0<<endl;
continue;
}
else
{
int total=0;
if(a>b)
{
while(a!=0&&b!=0)
{
a--;
if(a==0)
{
total+=1;
break;
}
b--;
if(b==0)
{
total-=1;
}
total+=2;
}
}
else
{
while(a!=0&&b!=0)
{
b--;
if(b==0)
{
total+=1;
break;
}
a--;
if(a==0)
{
total-=1;
}
total+=2;
}
}
cout<<total-1<<endl;
}
}
return 0;
}
两个的耗时好像没啥区别。。。(真是太失败了,然后我去翻了一下题解。***竟然这么简单,竟然有公式!!!)
ac代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
int a,b;
cin>>a>>b;
cout<<2*min(a,b)-2<<endl;//公式
}
return 0;
}