【URAL 刷题记】URAL 1600 ~ URAL 1607

URAL 1600

/*
题意: 给三维空间中n个点, 且每个点有平均飞行的向量. 问是否存在一个时间, 2个东西距离<=d

暴力枚举点对, 然后三分判最低点是不是小于等于d.如果是的话, 在其左侧二分寻找恰好距离为d的时间.
(我是直接取一个平面以后看成射线与圆的交点问题。。。) 
*/
#include<cstdio>
#include<cmath>

double eps=1e-8;

int dcmp(const double& x){ return fabs(x)<eps ? 0 : (x<0 ? -1 : 1); }

struct Point3{
    double x,y,z;
    Point3(){}
    Point3(double x,double y,double z):x(x),y(y),z(z){}
    bool operator ==(const Point3& B)const{ return dcmp(x-B.x)==0 && dcmp(y-B.y)==0 && dcmp(z-B.z)==0; }
    void read(){
        double x,y,z; scanf("%lf%lf%lf",&x,&y,&z);
        this->x=x, this->y=y, this->z=z;
    }
};
Point3 operator +(const Point3& A,const Point3& B){ return Point3(A.x+B.x,A.y+B.y,A.z+B.z); }
Point3 operator -(const Point3& A,const Point3& B){ return Point3(A.x-B.x,A.y-B.y,A.z-B.z); }
Point3 operator *(const Point3& A,const double& b){ return Point3(A.x*b,A.y*b,A.z*b); }
Point3 operator /(const Point3& A,const double& b){ return Point3(A.x/b,A.y/b,A.z/b); }
double Dot(const Point3& A,const Point3& B){ return A.x*B.x+A.y*B.y+A.z*B.z; }
double Length(const Point3& A){ return sqrt(Dot(A,A)); }
Point3 Cross(const Point3& A,const Point3& B){ return Point3(A.y*B.z-A.z*B.y, A.z*B.x-A.x*B.z, A.x*B.y-A.y*B.x); }

double DistanceToLine(const Point3& P, const Point3& A,const Point3& B){
    Point3 v1=B-A, v2=P-A;
    return Length(Cross(v1,v2))/Length(v1);
}
double DistanceToSegment(const Point3& P, const Point3& A,const Point3& B){
    if(A==B) return Length(P-A);
    Point3 v1=B-A, v2=P-A, v3=P-B;
    if(dcmp(Dot(v1,v2))<0) return Length(v2);
    else if(dcmp(Dot(v1,v3))>0) return Length(v3);
    else return Length(Cross(v1,v2))/Length(v1);
}
double DistanceToHalfline(const Point3& P, const Point3& A,const Point3& B){
    if(A==B) return Length(P-A);
    Point3 v1=B-A, v2=P-A;
    if(dcmp(Dot(v1,v2))<0) return Length(v2);
    else return Length(Cross(v1,v2))/Length(v1);
}

const int maxn=510;

int n; double D;

Point3 A[maxn],v[maxn];

double mit; int mix,miy;

double sqr(double x){ return x*x; }
void calc(){
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j)if(j!=i){
            if(Length(A[j]-A[i])<D){ mit=0,mix=i,miy=j; return; }
            double x=DistanceToHalfline(A[i],A[j],A[j]+(v[j]-v[i]));
            if(dcmp(x-D)<=0){
                double d1=sqrt(sqr(Length(A[j]-A[i]))-sqr(x)), d2=sqrt(sqr(D)-sqr(x));
                double t=fabs((d2-d1)/Length(v[j]-v[i]));

                if(dcmp(t-mit)<0){
                    mit=t; mix=i, miy=j;
                }
            }
        }
    }
}

void solve(){
    scanf("%d%lf",&n,&D);
    for(int i=1;i<=n;++i){
        A[i].read(); v[i].read();
    }

    mit=1e30; mix=-1;
    calc();

    if(mix==-1) puts("OK");
    else printf("ALARM!\n%.3lf %d %d\n",mit,mix,miy);
}

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

URAL 1601

/*
简单模拟题,将非句子开头的大写字母转化成小写即可,注意行首字母不一定大写
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cctype>

const int maxn=10010;

int n;
char s[maxn];
void solve(){
    int fst=1;
    while (gets(s)){
        n=strlen(s);
        for(int i=0;i<n;++i){
            if(isalpha(s[i])){
                if(fst){
                    putchar(toupper(s[i]));
                    fst=0;
                }else putchar(tolower(s[i]));
            }else putchar(s[i]);
            if(s[i]=='.' || s[i]=='!' || s[i]=='?') fst=1;
        }
        putchar('\n');
    }
}
int main(){
//  freopen("in.txt","r",stdin);
    solve();
//  for(;;);
    return 0;
}

URAL 1602

/*
C题:一个人坐电梯,一开始电梯在k层,电梯要先下到1层,人可以从n层先下到x层再叫电梯。。。

枚举人先走到哪层即可。。。

(注意,人按电梯,电梯才会上楼。。) 
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

const double eps=1e-8;

double dcmp(double x){ return fabs(x)<eps ? 0 : (x < 0 ? -1 : 1); }

int n,k; double u,v;
void solve(){
    scanf("%d%d%lf%lf",&n,&k,&u,&v);

    double mit=(n-1)*u; int mix=1;
    for(int x=n;x>=2;--x){
        double t1=(n-x)*u, t2=(k-1)*v+15;
        double tm=max(t1,t2)+(x-1)*v+5+(x-1)*v;
        if(dcmp(tm-mit)<0){ mit=tm; mix=x; }
    }
    printf("%d\n",mix);
}
int main(){
//  freopen("in.txt","r",stdin);
    solve();
//  for(;;);
    return 0;
}

URAL 1603

/*
题意:给4*4的填字格,组成单词的方法是:从一个格子开始向四周走,然后不能走到同一个格子,给m个单词问能否用这个方法组成。
题解:直接把所有可能的单词全做出来,判断即可
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;

const int maxn=10;

string res[100000]; int resN;

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

char mp[maxn][maxn];

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

bool vis[maxn][maxn];
void dfs(int x,int y,string now){
    vis[x][y]=1;
    res[resN++]=now;
    for(int d=0;d<4;++d){
        int X=x+dxy[d][0], Y=y+dxy[d][1];
        if(check(X,Y)&&!vis[X][Y]){
            dfs(X,Y,now+mp[X][Y]);
        }
    }
    vis[x][y]=0;
}

char now[maxn*maxn];
void solve(){
    for(int i=0;i<4;++i)
        scanf("%s",mp[i]);

    memset(vis,0,sizeof vis);
    for(int i=0;i<4;++i)
        for(int j=0;j<4;++j)
            dfs(i,j,string("") + mp[i][j]);

    sort(res,res+resN);
    int m;scanf("%d",&m);
    while(m--){
        scanf("%s",now); string nows=now;
        printf("%s: ",now);
//      cout << *lower_bound(res,res+resN,nows) << endl;
        if(nows==*lower_bound(res,res+resN,nows)) puts("YES"); else puts("NO");
    }

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

URAL 1604

/*
是给你n个数,有k种。要求把它们排成一列,使得相邻两个相同的情况尽可能少。

把出现次数最多的和次多的依次放就行了,搞个堆。
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;

typedef pair<int,int> P;

priority_queue<P> pq;

int k;
void solve(){
    scanf("%d",&k);
    for(int i=1;i<=k;++i){
        int x;scanf("%d",&x);
        pq.push(P(x,i));
    }

    while(!pq.empty()){
        P x=pq.top(); pq.pop();
        if(pq.empty()){
            for(int i=0;i<x.first;++i)
                printf("%d ",x.second);
            break;
        }
        P y=pq.top(); pq.pop();
        printf("%d %d ",x.second,y.second);
        if(x.first>1) pq.push(P(x.first-1,x.second));
        if(y.first>1) pq.push(P(y.first-1,y.second));
    }
    putchar('\n');
}
int main(){
//  freopen("in.txt","r",stdin);
    solve();
//  for(;;);
    return 0;
}

URAL 1605

/*
数列是逼近2/3的数列,所以xn是 k/2^n (0<=k<=2^n)里面最接近2/3的,然后奇数项小于2/3,偶数项大于2/3
通项公式 floor((2^i) * 2 / 3) + (i%2) 暴力求出这个数即可

c++的做法的话,通项公式
x_n = 2/3 + (1/3)/(2^(n-1)) n is odd
x_n = 2/3 - (1/3)/(2^(n-1)) n is even
观察后面一部分,设d=(1/3)/(2^(n-1))=0.00..0XXX..XX
可以知道,小数点后0的个数是k=floor[Log10(3)+(n-1)*Log10(2)] 
那么,
如果n is odd,如果d>0.00..0333..3(0的个数=k),那么答案输出k-1,否则输出k
如果n is even,如果d>0.00..0666..6(0的个数=k),那么答案输出k-1,否则输出k
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;

typedef long double LD;

int n;

void solve(){
    scanf("%d",&n);
//  if(n==100000) { puts("30102"); return; }
    LD t=log10(3)+(n-1)*log10(2);
    int k=(int)t;
    LD lgD=-t,lgA=(n&1) ? (-log10(3)-k) : (log10(2)-log10(3)-k);

//  cout << k << ' ' << (double)pow(10,lgA) << ' ' << (double)pow(10,lgD) << ' ' << (lgA>lgD) << endl;
//  printf("%d %d\n",pow(10,lgA)<=pow(10,lgD), lgA<=lgD);

    printf("%d\n",k-(lgA<=lgD));
}
int main(){
//  freopen("in.txt","r",stdin);

/*  double a=0,b=1,c;
    for(int t=0;t<10;++t){
        c=(a+b)/2;
        printf("%d %.10lf\n",t+2,c);
        a=b;b=c;
    }
*/  solve();
//  for(;;);
    return 0;
}

URAL 1606

/*
滑雪,从上到下,然后轨迹要是折线,拐点必须在桩上,而且每次都得转向(一次往左一次往右),然后最大化碰到的桩数

直接维护<x,>x数的最大值即可。 
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<functional>
using namespace std;

typedef pair<int,int> P;

const int maxn=100010;

int upd(int& a,int b){ return a<b ? a=b,1 : 0; }

int Tl[maxn],Tr[maxn],TN;
int Til[maxn], Tir[maxn];
void add(int* T,int* Ti,int x,int v,int i){ for(;x<=TN;x+=x&-x) if(upd(T[x],v)) Ti[x]=i; }
P sum(int* T,int* Ti,int x){ int v=-1,vi; for(;x;x-=x&-x) if(upd(v,T[x])) vi=Ti[x]; return P(v,vi); }

int g[maxn][2];

pair<P,int> a[maxn];

int n;

void print(int i,int j){
    if(g[i][j]) print(g[i][j],j^1);
    printf("%d ",a[i].second);
}

void solve(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        int x,y;scanf("%d%d",&x,&y);
        a[i]=make_pair(P(y,x),i);
    }
    sort(a+1,a+1+n,greater< pair<P,int> >());

    TN=100000;
    memset(Tl,0,sizeof Tl);
    memset(Tr,0,sizeof Tr);
    memset(Til,0,sizeof Til);
    memset(Tir,0,sizeof Tir);
    int res=-1; P resi;
    for(int i=1;i<=n;++i){
        int x=a[i].first.second, fl,fr;
        P p;
        p=sum(Tr,Tir,TN-(x+1)+1); fl=p.first+1, g[i][0]=p.second;
        p=sum(Tl,Til,x-1); fr=p.first+1, g[i][1]=p.second;
//      printf("%d %d\n",fl,fr);
        add(Tl,Til,x,fl,i); add(Tr,Tir,TN-x+1,fr,i);
        if(upd(res,fl)) resi=P(i,0);
        if(upd(res,fr)) resi=P(i,1);
    }
    printf("%d\n",res);
    print(resi.first, resi.second); putchar('\n');
}
int main(){
//  freopen("in.txt","r",stdin);

    solve();

//  for(;;);
    return 0;
}

URAL 1607

/*
题意: 乘客坐计程车, 乘客一开始出价a, 司机要价c, 两人没达成一致的话 乘客加b, 司机减d 问什么时候两人成交
模拟即可
注意特判
1. 如果一开始出价就满足,直接输出
2. 如果某次乘客加价超过司机价格,此时乘客直接按司机价格输出
3. 如果某次司机减价低于乘客价格,此时司机直接按乘客价格输出 
*/
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

int a,b,c,d;
void solve(){
    scanf("%d%d%d%d",&a,&b,&c,&d);
    for(;a<c;){
        if(a+b>=c){ a=c; break; }
        a+=b;
        if(c-d<=a)break;
        c-=d;
    }
    printf("%d\n",a);
}
int main(){
//  freopen("in.txt","r",stdin);
    solve();
//  for(;;);
    return 0;
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值