杭电的ACM 题 求助
http://acm.hdu.edu.cn/showproblem.php?pid=1030
这道题 我卡住一天了 ,样例和自己想的测试样例都可以过
题意是 一个三角形 里面很多个块 ,从1开始编号,那么给出 两个值a b 问你 从a走到 b 要多久
只能从 边走 ,不能从顶点跨过
# include<stdio.h># include<math.h>int main(){ //freopen("in.txt","r",stdin);freopen("myout.txt","w",stdout); long a,b; long i = 0,j=0;__int64 sa = 0,sb=0; long step = 0,temp = 0; while(scanf("%ld%ld",&a,&b)!=EOF) { i = (int)sqrt(a) ;j = (int)sqrt(b) ; sa = a - i*i; sb = b - j*j; i ++,j ++; // 计算出 行数 if(sa == 0) //当a 刚好是 平方数 的时候 行数要减一 { i --;sa = 2*i - 1; } if(sb == 0) { j--;sb = 2*j -1; } step = (j-i)*2; // 到达j 行所要的步数 if(sa >= sb) // 当啊 的起始位置 大于 B 时 step += sa - sb; else if(sa < sb) { if((sb-sa) < step) //这里考虑特殊情况 { if(sa%2==1 && sb%2 ==0) step --; else if(sa%2==0 && sb%2==1) step ++; } else { temp = sb - sa - step; step += temp; } } printf("%ld\n",step); } return 0;}
// 1234.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <cmath>using namespace std;int _tmain(int argc, _TCHAR* argv[]){ int n; int m; while(1){ cin>>n>>m; if(m < n){//确保m不小于n unsigned int iTemp = n; n = m; m = iTemp; } int iRow_n,iRow_m,iColumn_n,iColumn_m; iRow_n = (int) sqrt(double (n)); iColumn_n = n - iRow_n * iRow_n; if(iColumn_n){ -- iColumn_n; } else{ -- iRow_n; iColumn_n = n - iRow_n * iRow_n - 1; } iRow_m = (int) sqrt(double (m)); iColumn_m = m - iRow_m * iRow_m; if(iColumn_m){ -- iColumn_m; } else{ -- iRow_m; iColumn_m = m - iRow_m * iRow_m - 1; } int iColumn_n_Left = (iRow_n + 1) * (iRow_n + 1) - iRow_n * iRow_n - 1 - iColumn_n; int iColumn_m_Max = (iRow_m + 1) * (iRow_m + 1) - iRow_m * iRow_m; int iColumn_m_Left = iColumn_m_Max - 1 - iColumn_m; int iColumn_n_Right = iColumn_n; int iColumn_m_Right = iColumn_m; int iStep; if(iRow_m == iRow_n){ iStep = abs(iColumn_m - iColumn_n); } else{ if(iColumn_m < iColumn_n){ iStep = 2 * (iRow_m - iRow_n) + iColumn_n - iColumn_m; } else{ if(iColumn_m < iColumn_n + iRow_n + iRow_n){ iStep = 2 * (iRow_m - iRow_n - 1); int iOffset = iColumn_m % 2 * 2 + iColumn_n % 2; switch(iOffset){ case 0: iStep += 2; break; case 1: iStep += 3; break; case 2: iStep += 1; break; case 3: iStep += 2; break; default : break; } } else{ iStep = 2 * (iRow_m - iRow_n) + iColumn_m - (iColumn_n + iRow_n + iRow_n); } } } //cout<<"Row"<<iRow_n<<" "<<iRow_m<<endl; //cout<<"Column"<<iColumn_n<<" "<<iColumn_m<<endl; //cout<<"iStep"<<iStep<<endl; cout<<iStep<<endl; } return 0;}
[解决办法]
此题考点:DP(动态规划)
[解决办法]
#include<iostream>#include<cmath>using namespace std;int main(){ int slayer,elayer,cs,start,end; int sindex,eindex,width,height; while (cin>>start>>end) { if (start>end) { int temp = start; start = end; end = temp; } slayer = (int)ceil(sqrt((double)start)); //开根号取最小整数(ceil()函数)找出开始行 elayer = (int)ceil(sqrt((double)end)); //注意:求平方的时候如果用Pow()来求,可能会错 sindex = start - (slayer-1)*(slayer-1); //找出此数在当前行的位置。 eindex = end - (elayer-1)*(elayer-1); height = elayer - slayer; //两层之间的垂直距离 //用width和height比较可以确定end是否在start的2*height的辐射范围内。 width = abs(eindex-sindex-height); cs = 2*height; if (width>=height) { cs += width - height; //cs += abs(eindex-sindex-height)-height; } else { if(elayer%2==0&&end%2!=0||elayer%2!=0&&end%2==0) cs--; //判断elayer层的上层还是下层三角形里,从而是否减1 if(slayer%2==0&&start%2!=0||slayer%2!=0&&start%2==0) cs++; //判断elayer层的上层还是下层三角形里,从而是否加1 } cout<<cs<<endl; } return 0;}