Handstand 2
StarPatrick · · 题解
这是一道我们考试的题(我们的教练太勤快,居然在洛谷茫茫题海中找到了这道藏在角落中的题)。当时我用
来,废话不多说,下面步入正题。
第一种方法
首先,题目要求的数字对的两个数字,我们只需要知道它们的首尾就行了。
因此,我们可以把
最后,我们就可以计算答案,就是二维桶里所有数字的平方和(因为数对没有位置限制,所以这里是平方)。
时间复杂度
这里代码就不用展示了,因为代码量少,思路清晰简单。
第二种方法
这里如果听懂了上一种方法的可以跳过这种方法,不需要掌握,了解即可,因为一般这样的代码长,思维量大,出错率高,不建议在正式比赛采用。
在了解以下内容时,确保你已经看过@cqbzljt 的第三种方法。
各位读者可能已经知道,她的方法在考虑
这里,考虑这种情况的时候,答案其实可以通过数学方法算出来,因为首尾两端已确定,我们可以算出中间数字从而求出个数。
时间复杂度
献上我丑陋的代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define int long long
#define max(a,b) a>b?a:b
int n, L, R, ans, f[15][15], len = 1, i;
int quick(int a, int b)//快速幂
{
if (b<0)
{
return 0;
}
if (b==0)
{
return 1;
}
int mid = quick(a, b/2);
if (b%2==0)
{
return mid*mid;
}
else
{
return a*mid*mid;
}
}
signed main()
{
cin>>n;
if(n<10){//特判
cout<<n;
return 0;
}
L = n;
while (L>=10)
{
L/=10;
len++;
}
R = n%10;
i = (n-quick(10, len-1)*L)/10+1;
for (int l=1;l<=9;l++)
{
for (int r=1;r<=9;r++)
{
if (l<L)
{
f[l][r] = quick(10, len-1)/9;
}
else if (l>L)
{
f[l][r] = quick(10, len-2)/9;
}
else
{
if (r>R)//两种情况
{
f[l][r] = i-1+quick(10, len-2)/9;
}
else
{
f[l][r] = i+quick(10, len-2)/9;
}
}
if(l==r)
{
f[l][r]++;
}
}
}
for (int p=1;p<=9;p++)
{
for (int k=1;k<=9;k++)
{
ans+=f[p][k]*f[k][p];
}
}
cout<<ans;
return 0;
}