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;
}