优美数对

题目传送门
比赛传送门
这给题目十分简单

错因

赛中的时候,我想着,枚举首位和末位。然后用一些数学方法算出来。但是公式太优美,没有调试出来。

正解

顺着我的思路,可以考虑对于第\(i\)个数,我们把它的首位存在\(l_i\),末位存在\(r_i\)
然后我们统计答案,首先我们记\(cnt_{i,j}\)表示1~\(n\)中,有多少个数的首位为\(i\),末位为\(j\)。
那么枚举1~\(n\),然后\(cnt_{l_i,r_i}\)加一
我们可以重新枚举1~\(n\),然后把\(cnt_{r_i,l_i}\)加到答案里面。
总体十分巧妙
代码如下

#include<bits/stdc++.h>
using namespace std;

const int N=2e5+10;
int n,cnt[15][15],l[N],r[N];

int main(){
    freopen("you.in","r",stdin);
    freopen("you.out","w",stdout);
    cin.tie(0)->sync_with_stdio(0);
    cin>>n;
    for(int i=1;i<=n;i++){
        l[i]=i%10;
        int x=i;
        while(x>=10) x/=10;
        r[i]=x;
        cnt[l[i]][r[i]]++;
    }
    int ans=0;
    for(int i=1;i<=n;i++) ans+=cnt[r[i]][l[i]];
    cout<<ans<<endl;
}

0 条评论

目前还没有评论...