xjoi奋斗群群赛2

https://cn.vjudge.net/contest/183263#overview
[toc]

A - Odds and Ends

题意

  • 一组n个数,分割成连续的子串,使子串数量为奇数,每个子串长度为奇数,头尾都为奇数。

思路

  • 如果n为偶数,无法操作;如果n为奇数,不需分割,只需第一个数和最后一个数位奇数。

题解

#include<cstdio>

int main()
{
    int n,a[101];
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",a+i);
    if(!(a[1]&1)||!(a[n]&1)||!(n&1)) printf("No");
    else printf("Yes");
}

B - Tell Your World

题意

  • 平面上有一些点,用两条直线将他们全部串起来。

思路

  • 固定第一个点,枚举其他点与它相连成为第一条直线,其他点在这条或与它平行的同一条直线上。

题解

#include<cstdio>
const int MAXN=1010;  //当把MAXN赋为1000时出现了TLE
int n,y[MAXN];
double getk(int b)
{
    return (double)(y[b]-y[1])/(b-1);
}
double getb(double k)
{
    return (double)y[1]-k;
}
void input()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",y+i);
}
int trys(int m)
{
    double k=getk(m);
    double b1=getb(k),b2=b1;
//  printf("\n%llf %llf\n",k,b1);
    bool v[MAXN]={0};
    for(int i=1;i<=n;i++)
    if(k*i+b1==y[i]) v[i]=1;
    for(int i=1;i<=n;i++)
    {
        if(v[i]==0)
        {
            if(b2==b1) b2=y[i]-i*k;
            else{
                if(k*i+b2!=y[i]) return 0;
            }
        }
    }
    if(b2==b1) return -1;
    return 1;


}

int main()
{
    input();
    for(int i=2;i<=n;i++)
    {
        int t=trys(i);
        if(t==-1){
            printf("No");
            return 0;
        }
        if(t==1){
            printf("Yes");
            return 0;
        }
    }
    int tmp=y[1];
    for(int i=2;i<=n;i++) y[i-1]=y[i];
    y[n]=tmp;
    int t=trys(2);
    if(t==1){
        printf("Yes");
        return 0;
    }
    printf("No");
}

C - From Y to Y

题意

  • 对于一个字符串,把每个字符看成一个长度为1的串,合并两个串的代价是两串中每种相同字符的乘积的总合.输入一个数,求一个符合最小合成总合是这个数的串.

思路

  • 对于单字符种类的串,合成代价是n*(n-1)/2;把一个串中相同字符各自合并,在相互合并是最优方法.

题解

#include<cstdio>
#include<cmath>
const int N=100010;
int f(int x)
{
    return x*(x-1)/2;
}
float def(int x)
{
    return sqrt(x*2+0.25)+0.5;
}
int main()
{
    char c='a';
    int k;
    scanf("%d",&k);
    if(k==0) printf("shit");
    while(k>0)
    {
        int d=def(k);
        for(int i=1;i<=d;i++) printf("%c",c);
        c++;
        k-=f(d);
    }
}

D - Harmony Analysis

题意

  • 输入k,输出一个(1”<<”k)*(1”<<”k) 的矩阵,内容为”*”和“+”,使任意两行对应格的字符 相同和不同的数量相同。

思路

  • 二分,将矩阵分成四个相等的矩阵,右下角的与其他的相反.

题解

#include<cstdio>
const int MAXN=1024;
bool b[MAXN][MAXN];
void prework()
{
    for(int i=0;i<=8;i++)
    {
        for(int j=0;j<(1<<i);j++)
            for(int k=0;k<(1<<i);k++)
            {
                b[j+(1<<i)][k]=b[j][k];
                b[j][k+(1<<i)]=b[j][k];
                b[j+(1<<i)][k+(1<<i)]=!b[j][k];
            }
    }
}
int main()
{
    prework();
    int k;
    scanf("%d",&k);
    for(int i=0;i<1<<k;i++)
    {
        for(int j=0;j<1<<k;j++)
        b[i][j] ? printf("+") : printf("*");
        printf("\n");
    }
}

E - Bear and Prime Numbers

题意

  • 给出一些数,给出一个区间,求其中的质数能被列出的数整除的次数总合.

思路

  • 筛选法求质数被整除次数,前缀和优化

题解

#include <stdio.h>  
#include <string.h>  

const int N = 10000005;  

int n, m, v[N], g[N], s[N];  

void init() {  
    memset(v, 0, sizeof(v));  
    memset(g, 0, sizeof(g));  
    memset(s, 0, sizeof(s));  

    int a;  
    scanf("%d", &n);  
    for (int i = 0; i < n; i++) {  
        scanf("%d", &a);  
        g[a]++;  
    }  

    for (int i = 2; i < N; i++) {  
        if (v[i]) continue;  
        for (int j = i; j < N; j += i) {  
            if (g[j]) s[i] += g[j];  
            v[j] = 1;  
        }  
    }  
    for (int i = 1; i < N; i++) s[i] += s[i-1];  
}  

void solve() {  
    int a, b;  
    scanf("%d", &m);  
    for (int i = 0; i < m; i++) {  
        scanf("%d%d", &a, &b);  
        if (a >= N) a = N;  
        if (b >= N) b = N - 1;  
        printf("%d\n", s[b] - s[a-1]);  
    }  
}  

int main() {  
    init();  
    solve();  
    return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值