Codeforces Education round17

来源:互联网 发布:红豆薏米粉的品牌 知乎 编辑:程序博客网 时间:2024/06/06 09:49
这几天过年没怎么写题(说的好像没过年就在写题一样),把最近的比赛补一补吧

cf762A  

题意大概是给一个数字n,让我们求这个数字的因子并且从小到大排序后,求第k大的因子,如果不存在在输出-1

n<= 1e15 k<=1e9

这个数字看上去很吓人,但是仔细想一下,由于因子是成对出现的,我们只要枚举到sqrt(n)就能知道这个数字有多少因子,然后丢到一个集合里排序后输出即可,而且即使是1e15也没有1e7的因子。所以直接写就可以了。

#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<set>#include<map>#include<time.h>#include<cstdio>#include<vector>#include<stack>#include<queue>#include<iostream>using namespace std;#define  LONG long longconst int   INF=0x3f3f3f3f;const int MOD=1e9+7;const double PI=acos(-1.0);#define clrI(x) memset(x,-1,sizeof(x))#define clr0(x) memset(x,0,sizeof x)#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10LONG num[100000];int main(){    LONG n , k;    cin>>n>>k;    int tot = 0;    for(LONG i = 1 ; i* i <= n ;++ i)    {        if( i * i == n ) {num[ ++tot ] = i;break ;}        if(n % i == 0)        {            num[++ tot  ] = n/i;            num[++ tot ] = i;        }    }    sort( num + 1 , num + tot + 1);    if( k > tot )cout<<-1 <<endl;    else cout<<num[k]<<endl;}
cf 762B

 大概意思就是需要购进一批鼠标,有两种接口,现在实验室有只能插A接口的电脑a台,只能插B接口的电脑b台,两个接口都有的电脑c台,问我们在优先使得购进尽量多且合适的鼠标的前提下,最小的价格是多少
这道题我也不太能证明,就是先把鼠标按价格排序后,优先满足单一接口的电脑,然后剩下的给两个接口的电脑。过程比较简便。

#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<set>#include<map>#include<time.h>#include<cstdio>#include<vector>#include<stack>#include<queue>#include<iostream>using namespace std;#define  LONG long longconst int   INF=0x3f3f3f3f;const int MOD=1e9+7;const double PI=acos(-1.0);#define clrI(x) memset(x,-1,sizeof(x))#define clr0(x) memset(x,0,sizeof x)#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10struct Mouse{    int v ;    char name[50];}mouse[3500000];bool cmp( Mouse a , Mouse b){    return a.v < b.v;}int main(){    int a , b , c;    scanf("%d%d%d",&a,&b,&c);    int m ;    cin>>m;    for(int i = 1; i <=m ;++i)        scanf("%d",&mouse[i].v),        scanf("%s",mouse[i].name);    sort( mouse +1 , mouse + m +1 , cmp );    int tot = 0 ;    LONG sum_mon = 0;    for(int i =1 ;i <= m ;++ i)    {        if(mouse[i].name[0] == 'U')        {            if(a > 0)                a--;            else if( c > 0)                c -- ;            else continue ;            tot ++ ;            sum_mon += (LONG )mouse[i].v;        }        else        {            if(b > 0)                b-- ;            else if ( c > 0)                c -- ;            else continue ;            tot ++ ;            sum_mon += (LONG)mouse[i].v;        }    }    printf("%d %lld\n",tot , sum_mon);}
cf 763C  (双指针)
这道题我一开始读错了题意,后来看题解,又把把样例仔细看过才搞懂
题意大概就是给两个字符串,然后让我们把第二串去掉中间连续部分,使得剩下的前缀和后缀连起来是第一个串的子串,(这里子串含义类似于LCS,对于第一个串不需要连续,第二个串需要连续。) 并要求中间去掉部分最短,输出剩下的前后缀连起来的子串,如果不存在这个子串输出'-' 。两个串的长度均是1e5。
比如ABCBA    ABDEBA ,那么去掉中间连续部分DE,然后得到ABBA,ABBA是ABCBA的子串,且DE是满足条件的最短去掉的部分。
仔细分析一下,大概就是跟双指针有关的。由于这个子串是第二个串的前缀连上后缀(也有可能只是的后缀或者前缀),我们存一下第二个串的前缀每个字符到达第一个串的位置,
比如DABCBAE ABDEBA 得到2 3 -1  -1  -1  -1 (-1的意思就是这个字符匹配不上了,实际上为了方便可以把数组预设为INF,然后大于第一个串长度的都视为匹配不上)
同样的方式我们处理一下后缀部分,然后我们得到了两个数组
比如abacaba   abcdcba,得到1 2 4 -1 -1 -1 -1 和 -1 -1 -1 -1 4 6 7
我们现在要做的就是找到一对(i,j),j > i且bj > ai,同时j-i最小。 指针p1初始指向第一个数组的最后一个合法元素(合法元素指这里的字符能匹配的上,不是-1或者INF)指针p2初始指向第二个数组最后一个元素再往后移动一位的位置。
然后p2每次向前移动一位,如果p2<=p1或者b[p2]<=a[p1],p1向前移动一位,然后每次维护一下p2 - p1的min值。注意一下有可能只去掉前缀或者只去掉后缀,边界问题处理一下

#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<set>#include<map>#include<time.h>#include<cstdio>#include<vector>#include<stack>#include<queue>#include<iostream>using namespace std;#define  LONG long longconst int   INF=0x3f3f3f3f;const int MOD=1e9+7;const double PI=acos(-1.0);#define clrI(x) memset(x,-1,sizeof(x))#define clr0(x) memset(x,0,sizeof x)#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10int num [30][100100];char str1[100100];char str2[100100];int a[100100];int b[100100] ;int main(){    clr1( a );    clrI( b ) ;    scanf("%s%s",str1 , str2 );    int len1 = strlen(str1);    int len2 = strlen(str2);    int j,i;    j = 0;    for( i = 0 ; i < len2 ;++ i)    {        while(str1[j] != str2[i] && j < len1) ++ j;        if( j >= len1)break ;        a[i] = j ;        j++;    }    int p1 = i - 1;    j = len1 - 1;    for( i = len2 - 1 ; i >= 0 ; -- i)    {        while ( str1[j] != str2[i] && j >= 0) -- j;        if(j < 0 )break ;        b[i] = j;        -- j;    }    int p2;    if(b[len2 - 1] > a[p1]) p2 = len2 - 1;    else p2 = len2 ;    int res = p2 - p1;    for( i = p1 , j = p2 ; ; )    {        if(  j < 0  || b[j] == -1&& j < len2)break ;        if(i >= 0)        if(a[i] >= b[j]|| j <= i)        {            -- i;        }        if(res > j - i)        {            res = j - i;            p1 = i , p2 =  j;        }        j -- ;    }    if(p1 < 0 && p2 >= len2)cout<<'-'<<endl;    else{        if( p1 == p2 ) p2 ++ ;        for( i = 0 ; i <= p1 ; ++ i)printf("%c",str2[i]);        for( i = p2 ; i <= len2 -1 ; ++ i) printf("%c",str2[i]);}}




1 0
原创粉丝点击