链接:http://codeforces.com/contest/677
c:Vanya and Label
题意:给你一个字符串s,每个字符可以用一个10进制数表示(0~63),现在要求有多少对与s长度一样的字符串通过&得到s。
分析:只用64个数,直接暴力出每两个数的&,然后相乘就行了。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 50010
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
ll get(char p) {
int x=0;
if(p>='0'&&p<='9') x=p-'0';
else if(p>='a'&&p<='z') x=p-'a'+36;
else if(p>='A'&&p<='Z') x=p-'A'+10;
else if(p=='-') x=62;
else if(p=='_') x=63;
return x;
}
int a[70];
int main() {
for(int i=0;i<64;i++) {
for(int j=0;j<64;j++) {
a[i&j]++;
}
}
string s;
cin>>s;
ll sum=1;
for(int i=0;i<s.size();i++) {
sum=(sum*a[get(s[i])])%mod;
//cout<<sum<<endl;
}
cout<<sum<<endl;
return 0;
}
D:Vanya and Treasure
题意:给你一个n*m的矩阵,其中的数由1~p组成,现在要你找到一个1,2,.....p的顺序的最短曼哈顿距离。
分析:我们可以将所有相同值得分成一个点集,然后由i的所有点更新到i+1的所有点,更新过程如下:
将i的所有点的横轴标记为i,并且计算出他们最小距离,然后到i+1中所有点的距离就是由纵轴上的i更新过来的。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 300*300+5
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
vector<int> a[Mn];
int ans[Mn];
int dis[Mn];
int vis[Mn];
int main() {
int n,m,p,x;
cin>>n>>m>>p;
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
scanf("%d",&x);
a[x].push_back(i*m+j);
}
}
CLR(dis,0x3f);
CLR(ans,0x3f);
for(int i=0;i<m;i++) {
dis[i]=i;
vis[i]=0;
}
for(int i=1;i<=p;i++) {
for(auto now:a[i]) {
int a2=now/m,b2=now%m;
for(int j=0;j<n;j++) {
int pre=j*m+b2;
if(vis[pre]==i-1) {
ans[now]=min(ans[now],dis[pre]+abs(j-a2));
}
}
}
for(auto now:a[i]) {
int a2=now/m,b2=now%m;;
for(int j=0;j<m;j++) {
int ne=a2*m+j;
if(vis[ne]!=i) {
vis[ne]=i;
dis[ne]=ans[now]+abs(b2-j);
} else {
dis[ne]=min(dis[ne],ans[now]+abs(b2-j));
}
}
}
}
cout<<ans[a[p][0]]<<endl;
return 0;
}