牛客挑戰賽18 C異或和 (加深下對哈曼頓距離的理解)
阿新 • • 發佈:2018-06-24
coder scanf fin board 貢獻 brush true mat TE
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld
9
鏈接:https://www.nowcoder.com/acm/contest/129/C
來源:牛客網
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld
題目描述
有一個n*m的網格圖,給出小B出現在每個位置的可能性,用一個n*m的01矩陣表示,小B等概率出現在所有1的位置。求小A在每個位置上與小B期望曼哈頓距離的異或和,先把期望取模之後再異或輸入描述:
第一行讀入兩個整數 n,m (n,m <= 2000)
接下來n行,每行讀入一個長度為m的01字符串。
輸出描述:
輸出一個整數表示答案模 10
+7示例1
輸入
復制1 3 101
輸出
復制1
說明
小A出現在(1,1)的時候期望曼哈頓距離是1
小A出現在(1,2)的時候期望曼哈頓距離是1
小A出現在(1,3)的時候期望曼哈頓距離是1
答案是這三者的異或和。
#include<bits/stdc++.h> #include<cstring> #define ll long long using namespace std; const int maxn = 2e3 + 7; const ll mod = 1000000007; ll h[maxn],l[maxn]; int n,m; char mp[2022][2022]; ll a[maxn], b[maxn], ans, Ans; ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;} int main() { ll cnt=0; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { getchar(); for (int j=1;j<=m;j++) { mp[i][j]=getchar(); if (mp[i][j]==‘1‘) cnt++,h[i]++,l[j]++; } } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[j]+=abs(i-j)*h[i]; for (int i=1;i<=m;i++) for (int j=1;j<=m;j++) b[j]+=abs(i-j)*l[i]; ll hh = fpow(cnt,mod-2); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) ans^=(ll)(a[i]+b[j])*hh%mod; cout<<ans<<endl; return 0; }
加深的理解是對於 哈曼頓距離可以分開求x,y>>其次對於同一行的點來說>>哈曼頓距離的貢獻是一樣的
這個題寫不出來的話,純屬對哈曼頓距離的理解不夠深>>我覺得acm確實需要系統的學習>>要不你就是有系統的學習要不你就得拼刷題量..
牛客挑戰賽18 C異或和 (加深下對哈曼頓距離的理解)