您的位置:首页 > 其它

【URAL 刷题记】URAL 1028 ~ URAL 1035

2016-02-05 19:43 393 查看
URAL 1028

/*
题意:求左下角点的个数。。。
题解:把点按照x坐标排序,y轴建一棵树状数组即可。。
*/
#include<algorithm>
#include<cstdio>
using namespace std;

typedef pair<int,int>P;

const int MAXN=40000;
int T[MAXN];
void add(int x, int v){ for(; x<MAXN; x+=x&-x) T[x]+=v; }
int sum(int x){ int v=0; for(;x;x-=x&-x) v+=T[x]; return v; }

const int maxn=15010;

P A[maxn];
int res[maxn];
int n;

int main(){
//  freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=0;i<n;++i){
int x,y;scanf("%d%d",&x,&y); ++x,++y;
A[i]=P(x,y);
}
sort(A,A+n);
for%53C%"5�Fspan>(int i=0;i<n;++i){
int x=sum(A[i].second);
res[x] ++;
add(A[i].second,1);
}
for(int i=0;i<n;++i)printf("%d\n",res[i]);
//  for(;;);
return 0;
}


URAL 1029

/*
题意:求出从第一层楼到第m层楼的最少花费, i-1楼的k房间可以到i楼的k房间, 同一楼层相邻的房间可以联通(差1)
题解:直接对每一层往右往左刷一遍(因为权值为正,所以不可能绕弯。),上下更新一把即可。
*/

#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

typedef long long LL;

const int maxn=10010;

int n,m;
int A[maxn][maxn], f[maxn][maxn], g[maxn][maxn];

void dfs(int d,int i,int j){
if(i==0)return;
if(g[i][j]!=j)dfs(d+1,i,g[i][j]); else dfs(d+1,i-1,j);
printf("%d%c", j,d==0?'\n':' ');
}
void solve(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%d",&A[i][j]);
for(int j=1;j<=m;++j)
f[0][j]=0;

for(int i=1;i<=n;++i) {
for(int j=1;j<=m;++j)
f[i][j]=f[i-1][j]+A[i][j],g[i][j]=j;
for(int j=m-1;j>=1;--j)
if(f[i][j]>f[i][j+1]+A[i][j])
f[i][j]=f[i][j+1]+A[i][j],g[i][j]=j+1;
for(int j=2;j<=m;++j)
if(f[i][j]>f[i][j-1]+A[i][j])
f[i][j]=f[i][j-1]+A[i][j],g[i][j]=j-1;
}
int x=min_element(f
+1,f
+m+1)-f
;
dfs(0,n,x);
}

int main(){
//  freopen("in.txt","r",stdin);
solve();
//  for(;;);
return 0;
}


URAL 1030

/*
给出船只和冰山的经纬度,求出它们之间的距离,并判断其是否大于100
解法:
球面的距离公式:R*acos( sin(x1)*sin(x2)+cos(x1)*cos(x2)*cos(y1-y2) )/2;
这里x是纬度,y是经度,计算之前所有的经纬度都要化为弧度制
R=6875,题目里有给

我是先把球坐标系转化为三维坐标系,然后求角度做的。。。。 https://en.wikipedia.org/wiki/Spherical_coordinate_system 注意一下这里有两幅图,角度表示是不同的。。。所以可能到时图片公式不配套(Baidu百科好坑。。)
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

const double EarthR=6875.0/2;
const double PI=acos(-1.0);

double sqr(double x){ return x*x; }

char s[4][10], t[4][10];

double getang(char *s){
double res=0;
char *p=strtok(s,"^'\"");
res+=atoi(p);
p=strtok(0,"^'\"");
res+=atoi(p)/60.0;
p=strtok(0,"^'\"");
res+=atoi(p)/60.0/60.0;
res=res/180.0*PI;
return res;
}

double ang[4];
double x[2],y[2],z[2];

void solve(){
scanf("%*s%*s%*s%*s%*s%*s%*s%*s%*s%s%s%*s%s%s%*s%*s%*s%*s%*s%s%s%*s%s%s%*s",s[0],t[0],s[1],t[1],s[2],t[2],s[3],t[3]);

for(int i=0;i<4;++i) {
double a=getang(s[i]);
switch (t[i][0]) {
case 'N': ang[i]=a; break;
case 'S': ang[i]=PI-a; break;
case 'E': ang[i]=a; break;
case 'W': ang[i]=-a; break;
}
}
//  swap(ang[0],ang[1]);
//  swap(ang[2],ang[3]);
x[0]=sin(ang[0])*cos(ang[1]), y[0]=sin(ang[0])*sin(ang[1]), z[0]=cos(ang[0]);
x[1]=sin(ang[2])*cos(ang[3]), y[1]=sin(ang[2])*sin(ang[3]), z[1]=cos(ang[2]);
double d=sqrt(sqr(x[1]-x[0])+sqr(y[1]-y[0])+sqr(z[1]-z[0]));

double rad=acos((2-d*d)/2);
printf("%.2lf\n", EarthR*rad);
}

int main(){
freopen("in.txt","r",stdin);
solve();
for(;;);
return 0;
}


URAL 1031

/*
题意:火车有三种区间票,花费Ci可以坐Li距离,然后求两点之间最小花费
题解:因为f[]有单调性所以直接二分一把即可。
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

constbool fg=0;
for(int i=1;i<=3;++i)if(per[i]==i){ fg=1;break; }
if(fg) continue;
mp[x[p[1]]][y[p[per[1]]]]=1;
mp[x[p[2]]][y[p[per[2]]]]=1;
mp[x[p[3]]][y[p[per[3]]]]=1;
if(check(x[p[1]],y[p[per[1]]]) && check(x[p[2]],y[p[per[2]]]) && check(x[p[3]],y[p[per[3]]])){
/*                      for(int i=1;i<=n;++i,putchar('\n'))
for(int j=1;j<=n;++j,putchar(' '))
printf("%d",mp[i][j]);
putchar('\n');
*/                      ++ res;
}
mp[x[p[1]]][y[p[per[1]]]]=0;
mp[x[p[2]]][y[p[per[2]]]]=0;
mp[x[p[3]]][y[p[per[3]]]]=0;
} while(next_permutation(per+1,per+1+3));
mp[x[p[1]]][y[p[1]]]=1;
mp[x[p[2]]][y[p[2]]]=1;
mp[x[p[3]]][y[p[3]]]=1;
}
printf("%d\n",res);
}

int main(){
//  freopen("in.txt","r",stdin);
solve();
//  for(;;);
return 0;
}


URAL 1035

/*
题意:给出一幅十字绣的图案,询问最少的穿针次数(前m*n是正面图案,后m*n是背面图案)
一次穿针的要求�%�C%yA0A1:线头如果从正面穿入,那么必然从正面穿出,而且之后便翻转方向,即从那个位置开始反面穿针。反过来亦如此
2:线头如果到了格点,那么必须翻转方向,而且只能在格点翻转方向
3:针在不反转方向的情况下,一次只能穿1*1的格子的对角线
(好像就这些了,其实就是平常穿针的要求=_=)

解法:这是个一笔画问题,然而却不好建图
于是我们可以考虑从点的度数下手
由于不同的连通块(图案)之间,是无法用同一根针穿起来的,所以我们考虑一个连通块时候的情况,之后再将答案相加
对某个点,定义针需要从正面穿入穿出的为入度,从反面穿入穿出的为出度
那么在一个连通图中,一个点对度数的贡献就是入度和出度之差的绝对值
一个连通块对答案的贡献就是所有点的度数贡献之和除以2,如果之和为0的话那么贡献就是1.
*/

#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

typedef long long LL;

const int maxn=210;

char mp0[maxn][maxn];
int mp[maxn][maxn], fg[maxn][maxn];
int n,m;

void read(int v){
for(int i=0;i<n;++i)
for(int j=0;j<m;++j){
char x; scanf(" %c",&x);

if(mp0[i][j]=='.') mp0[i][j]=x;
else if((mp0[i][j]=='/' && (x=='\\' || x=='X')) || (mp0[i][j]=='\\' && (x=='/' || x=='X')))
mp0[i][j]='X';

if(x=='\\'||x=='X'){
mp[i][j]+=v; mp[i+1][j+1]+=v; fg[i][j]=fg[i+1][j+1]=1;
}
if(x=='/'||x=='X'){
mp[i][j+1]+=v; mp[i+1][j]+=v; fg[i][j+1]=fg[i+1][j]=1;
}
}

}

const int dxy[4][2]={{1,-1},{-1,1},{1,1},{-1,-1}};

bool check0(int x,int y){ return 0<=x&&x<n&&0<=y&&y<m; }
bool check(int x,int y){ return 0<=x&&x<=n&&0<=y&&y<=m; }

int s;
bool dfs(int x,int y){
s+=abs(mp[x][y]);
//  printf("%d %d %d\n",x,y,s);
fg[x][y]=0;

if(check0(x,y-1) && (mp0[x][y-1]=='/'||mp0[x][y-1]=='X')){
int d=0;
int X=x+dxy[d][0], Y=y+dxy[d][1];
if(check(X,Y) && fg[X][Y])
dfs(X,Y);
}
if(check0(x-1,y) && (mp0[x-1][y]=='/'||mp0[x-1][y]=='X')){
int d=1;
int X=x+dxy[d][0], Y=y+dxy[d][1];
if(check(X,Y) && fg[X][Y])
dfs(X,Y);
}
if(check0(x,y) && (mp0[x][y]=='\\'||mp0[x][y]=='X')){
int d=2;
int X=x+dxy[d][0], Y=y+dxy[d][1];
if(check(X,Y) && fg[X][Y])
dfs(X,Y);
}
if(check0(x-1,y-1) && (mp0[x-1][y-1]=='\\'||mp0[x-1][y-1]=='X')){
int d=3;
int X=x+dxy[d][0], Y=y+dxy[d][1];
if(check(X,Y) && fg[X][Y])
dfs(X,Y);
}
}

void solve(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i) for(int j=0;j<m;++j) mp0[i][j]='.';
read(1); read(-1);
int res=0;
for(int i=0;i<=n;++i)
for(int j=0;j<=m;++j)if(fg[i][j]){
s=0;
dfs(i,j);
s=s/2;
//          printf("%d %d %d\n===========\n",i,j,s);
res+=(s==0?1:s);
}
printf("%d\n",res);
}

int main(){
//  freopen("in.txt","r",stdin);
solve();
//  for(;;);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  URAL