【TYVJ水题三连发】1502 兴建高铁 1568 Rabbit Number 1673 位图
说是水题。。其实本蒟蒻1A的也只有第二道。。。惭愧惭愧。。。
TYVJ1502 兴建高铁
这个题目其实就是一搜索,愿意BFS或者DFS都可以,SPFA也随意。不过鉴于数据不大,推荐还是DFS(写起来比较短嘛)
Code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
int n,ans=99999999,tot=99999999;
int g[51][51],v[51],w[51],p[51];
void dfs(int now,int max1,int max2,int cost,int pass){
p[pass]=now;
if (now==1){
int pp;
switch (pass){
case 1:pp=cost;break;
case 2:pp=cost-max1;break;
default:pp=cost-max1-max2;break;
}
if ((pp<ans)||((pp==ans)&&(pass<tot))){
ans=pp;tot=pass;
for (int i=1;i<=pass;i++) w[i]=p[i];
}
}
for (int i=1;i<=n;i++)
if ((g[now][i])&&(!v[i])){
v[i]++;
if (g[now][i]>=max1) dfs(i,g[now][i],max1,cost+g[now][i],pass+1);
else if (g[now][i]>=max2) dfs(i,max1,g[now][i],cost+g[now][i],pass+1);
else dfs(i,max1,max2,cost+g[now][i],pass+1);
v[i]--;
}
}
int main(){
cin >>n;
for (int i=1;i<=n;i++){
int a,b,c;
cin >>a >>b >>c;
g[a][b]=g[b][a]=c;
}
v[0]++;
dfs(0,0,0,0,0);
cout <<0;
for (int i=1;i<=tot;i++) cout <<" " <<w[i];
cout <<" " <<ans <<endl;
//while(1);
return 0;
}
TYVJ1568 Rabbit Number
这个题目第一反应是打表,第二反应还是打表。
不过后来发现在程序里算也不会超,关键是搜的时候要注意一点:组成Rabbit Number的数位不可能达到4(证明很简单。。不行题解里也有),然后就随便搜搜就可以了。
Code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <vector>
#define sqr(a) a*a
using namespace std;
const long limit=1000000001;
int all=0;
long long num[100001];
long long calc(long long x){
int now=0;
while (x){
now+=x%10;
x=x/10;
}
return now;
}
int check(long long x){
if (calc(sqr(x))==sqr(calc(x)))
return 1;
else return 0;
}
void dfs(long long now){
//cout <<now <<endl;
if (now>limit) return;
if (check(now)) {
all++;
num[all]=now;
}
if (now) dfs(now*10);
dfs(now*10+1);
dfs(now*10+2);
dfs(now*10+3);
}
int main(){
long long l,r;
memset(num,0,sizeof(num));
cin >>l >>r;
dfs(0);
all+=10;
sort(num,num+all);
int b=1,e=all;
while (!num[b]) b++;
while (!num[e]) e--;
while (num[b]<l) b++;
while (num[e]>r) e--;
cout <<e-b+1 <<endl;
return 0;
}
TYVJ1673 位图
这题目一开始还困扰了我很久。。
打开题解,一句”用广搜可过“让我压力巨大。。
后来发现,原来不是对每个点搜最近的白点,而是从白点开始floodfill。。这样就可以秒杀了。。
我还是太弱了。。。
Code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <vector>
#define sqr(a) a*a
using namespace std;
const int dx[5]={0,1,-1,0,0};
const int dy[5]={0,0,0,1,-1};
int l,r,n,m;
int v[201][201],s[100001][2];
int main(){
char c;
scanf("%d %d\n",&n,&m);
l=1;r=0;
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
scanf("%c",&c);
while ((c!='0')&&(c!='1')) scanf("%c",&c);
if (c=='0') v[i][j]=0;
else{
r++;s[r][1]=i;s[r][2]=j;
v[i][j]=1;
}
}
}
while (l<=r){
for (int i=1;i<=4;i++){
int nowx=s[l][1]+dx[i],nowy=s[l][2]+dy[i];
if ((nowx)&&(nowy)&&(nowx<=n)&&(nowy<=m)&&(!v[nowx][nowy])){
v[nowx][nowy]=v[s[l][1]][s[l][2]]+1;
r++;s[r][1]=nowx;s[r][2]=nowy;
}
}
l++;
}
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
if (j!=1) cout <<" ";
cout <<v[i][j]-1;
}
cout <<endl;
}
return 0;
}

浙公网安备 33010602011771号