Codeforces Round #450 (Div. 2)

http://codeforces.com/contest/900
好菜的说qwq
A
给定一些点,问可否去掉一个点是,使这些点都在y轴的一侧。
四种情况。

#include <bits/stdc++.h>
using namespace std;
int main()
{   int m,a,b;
int sum1=0;
int sum2=0;
    scanf("%d",&m);
     for(int i=0;i<m;i++){
         scanf("%d%d",&a,&b);
         if(a>0)
            sum1++;
         if(a<0)
            sum2++;
     }
     bool flag=false;
    if(!sum1||!sum2)
        flag=true;
    if(sum1==1||sum2==1)
        flag=true;
    if(flag)
        puts("Yes");
    else
        puts("No");
    return 0;
}

B
有一点数学知识,我是很差的qwq,所以不太会。
给定 a b,c,要求a/b组成的小数中c最早出现的位数是多少。
如果一个数字可以被分数表示,肯定不是无限不循环小数,并且再竖式运算中,有限小数每次对除数mod的数不会出现许多次。如果出现了多次那么就出现了循环节(除数不变嘛),然后我们就可以break。但是那个小数是可以出现 重复的数字的qwq。
判断的时候注意先判断d再判断是否是循环节,因为最后可能出现了两次

#include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
int gcd(int a,int b)
{
    int c;
    while(b)
    {
        c=a%b;
        a=b;
        b=c;
    }
    return a;
}
map<int,bool>mp;
int main()
{
    int a,b,c,d,e,i;
    scanf("%d%d%d",&a,&b,&c);
    d=gcd(a,b);
    a/=d;
    b/=d;
    d=a/b;
    a-=d*b;
    a*=10;
    bool flag=false;
    int aim=1;
    for(i=1;;i++)
    {
        d=a/b;
        a-=d*b;

            if(d==c) {
                    flag=true;
                   aim=i;

                   //cout<<"!!"<<endl;
                    break;}
                    if(mp[a]){
          //cout<<"??"<<endl;
          break;
            }
        mp[a]=true;
        //cout<<a<<endl;
        a*=10;
    }
    if(!flag)
        printf("-1\n");
    else
        printf("%d\n",aim);
    return 0;
}
#include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
int gcd(int a,int b)
{
    int c;
    while(b)
    {
        c=a%b;
        a=b;
        b=c;
    }
    return a;
}
int main()
{
    int a,b,c,d,e,i;
    scanf("%d%d%d",&a,&b,&c);
    d=gcd(a,b);
    a/=d;
    b/=d;
    d=a/b;
    a-=d*b;
    a*=10;
    for(i=1;i<b+1;i++)
    {
        d=a/b;
        a-=d*b;
        if(d==c)
            break;
        a*=10;
    }
    if(i>=b+1)//这个是次数,不会超过 分母次。
        printf("-1\n");
    else
        printf("%d\n",i);
    return 0;
}

C是思维。貌似用BIT也能写。
给定一个数组,一个数字被称为record数,当他前面没有比他大的数字。
问去掉一个数字,使数组中的reocd数最大。
开始以为是 最长上升子序列。。关键是去掉哪个。并且最长上升子序列(LIS)有时会发生变化(比如 1 4 5 2 3,可以是 1 4 5,也可以是 1 2 3),这就搞的我很慌,后来我想根据他在LIS中的位置(从后往前那样推)。然后把 lis中 可以做位置x的放到一个vector里,然后我发现发现位置1是不能确定的,因为初始化 的lis就是1qwq。
xjb搞也是一直错qwq。先放一放把。
过了几天看了正解:维护最大值次小值,因为我们可以发现一个道理,那个道理就是 当一个数 大于之前的max时,去掉他才会使 record-1.
当他后面他的数 只小于他,那么他就可以 +record。
看代码就好,num[i]的意思是 去掉i会让record增加的数目

#include <bits/stdc++.h>
using namespace std;
/*维护最大值和次大值。对于一个元素来说,
删除他的时候,recodrd数减小,要求他是最大的。
如果要record数增加,要求他是 当前区间最大的。
而整个过程可以线性维护
。
qwq,其实我一直觉得这种题吊吊的
*/
const int maxn=1e5+2;
int num[maxn];
int main(){
    int n,x;
    scanf("%d",&n);
    int max1=-1e9;
    int max2=-1e9;
    for(int i=0;i<n;i++){
        scanf("%d",&x);
        if(x>max1){
            max2=max1;
            max1=x;
            num[x]--;
        }
        else if(x>max2){
             num[max1]++;
             max2=x;
        }
    }
    int res=1;
    for(int i=1;i<=n;i++){
        if(num[i]>num[res]){
             res=i;
        }
    }
    printf("%d\n",res);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值