notas título Escova - dicotomia

intervalo de números

Dado um comprimento na ordem de uma matriz de números inteiros n ascendente, e consultas q.
Para cada consulta, um elemento de retorno k iniciar e as posições de extremidade (posição de contagem de 0).
Se o elemento não está presente na matriz, "-1-1" é retornado.

Formato de entrada

A primeira linha contém um inteiro n e q, e o comprimento da matriz representa o número de interrogação.
A segunda linha contém n inteiros (ambos na gama de 1 a 10000), indicando a matriz completa.
Próximo linhas q, cada linha contém um inteiro k, representa um elemento de consulta.

Formato de saída

Um total de linhas de q, cada fileira compreende dois números inteiros que representam as posições de início e de fim dos elementos necessários.
Se o elemento não está presente na matriz, "-1-1" é retornado.

Intervalo de dados

1≤n≤100000
1≤q≤10000
1≤k≤10000

ideias:

1. Localize o ponto de esquerda:
- o intervalo [0 ,. 1-n-]
- condições Analisando: Num [meados]> = o alcatrão
2. Encontrar o ponto certo:
- o intervalo [endpoint esquerda ,. 1-n-]
- condições Analisando: num [meio] <= alcatrão

código:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n,q;
int num[N];
int main(void)
{
    scanf("%d %d",&n,&q);
    for(int i = 0;i < n;i++)
        scanf("%d",&num[i]);
    while(q--)
    {
        int tar;
        scanf("%d",&tar);
        
        //找左端点
        int l = 0,r = n-1;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(num[mid] >= tar) 
                r = mid;
            else
                l = mid + 1;
        }
        if(num[l] != tar)
            printf("-1 -1\n");
        else
        {
            printf("%d ",l);
            //找右端点
            r = n - 1;
            while(l < r)
            {
                int mid = l + r + 1 >> 1;
                if(num[mid] <= tar)
                    l = mid;
                else
                    r = mid - 1;
            }
            printf("%d\n",l);
        }
    }
	return 0;

}

problema robô salto

Robot está jogando um velho jogos baseados em DOS.
O jogo tem edifícios N + 1 - numeradas de 0 a N, da esquerda para a direita.
No. 0 altura do edifício é 0 unidades, a construção de altura numeradas i é unidades de H (i).
Inicialmente, a construção do robô no número zero.
Cada passo, ele salta para o próximo (à direita) arquitetura.
No pressuposto de k-th de que a construção do robô, e é agora um valor de energia E, ele saltará para o passo seguinte k + 1-th edifício.
Se H (k + 1)> E , em seguida, o robô irá perder H valor energético -E (+ 1 k), caso contrário ele irá obter o valor de energia EH (k + 1) do.
O objetivo do jogo é chegar a N-th edifício, o valor de energia neste processo não pode ser unidades negativos.
A questão agora é quanto valores de energia robô para iniciar o jogo, você pode garantir a conclusão bem sucedida do jogo?

Formato de entrada

A primeira linha do N. entrada inteiro
A segunda linha é um espaço separado inteiro N, H (1), H ( 2), ..., h (n) representante da altura do edifício.

Formato de saída

Saída de um valor inteiro representa uma unidade mínima inicial de energia necessária.

Intervalo de dados

\ (1≤N, H (i) ≤10 ^ 5 \)
\ (1≤N, H (i) ≤10 ^ 5 \)

ideias:

1. Analisar tópico

  • Se a quantidade de energia que o robô tem toda a altura do prédio de MAX, em seguida, o robô será capaz de passar todo o edifício, porque a altura do edifício menor que a energia para o número, o número irá aumentar a energia, construção em altura é igual ao número de energia, a energia vai aumentar o número 0.
  • E o robô tem um número de energia mínima que deve ser 1, porque a altura mínima do edifício é 1

2. dicotomia

  • Intervalo [1, max]
  • condições Analisando CAL (mid)> = 0, ou seja, um valor de energia para um meio, definir uma função cal (int x) para julgar, se deixados no edifício por toda a energia for maior que 0, o que indica que o valor da energia inicial pode também continuar a encolher.

código

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
const int N = 100010;
int n;
int num[N];
int cal(int x,int ma)             
{
    for(int i = 1; i <= n;i++)
    {
        if(x >= num[i])
            x += (x - num[i]);
        else
            x -= (num[i] - x);
        if(x < 0 || x >= ma)     //如果超过max,则一定可以通过;如果小于0,则一定不行
            break;
    }
    return x;
}

int main(void)
{
    scanf("%d",&n);
    int ma = 0;
    for(int i = 1 ;i <= n; i++ )
    {
        scanf("%d", &num[i]);
        ma = max(ma,num[i]);
    }
    //二分法    
    int l  = 1,r = ma;
    while(l < r)
    {
        int mid = (l + r) >> 1;
        if(cal(mid,ma) >= 0) 
            r = mid;
        else
            l = mid + 1;
    }
    printf("%d",r);
    return 0;
    
}

Eu encontrei o poço

Analisando a função CAL () não está no início

if(x < 0 || x >= ma)     
     break;

Os dados podem levar a estouro int x, x variam após a péssima falta acumulando, eu uso a longo longos x resultados estouro. Por fim, adicione o julgamento acima para pensar como condições, nem rápido nem estouro.

pontos de chocolate

Children 's crianças dia para ter um K-bit casa Xiaoming convidado. Xiao Ming para chegar a uma coleção de chocolate para entreter as crianças. XiaoMing um total de N blocos de chocolate, em que o bloco de ordem i é um rectângulo de Oi x quadrados Wi da mesma.

Para ser justo, as necessidades de BOB para estes N K cortar um pedaço de chocolate de chocolate dado a crianças. Recorte necessidades de chocolate atendidos:

  1. A forma é um quadrado com um comprimento de lado de um número inteiro
  2. O mesmo tamanho

Por exemplo um chocolate de 6x5 podem ser cortadas para fora do chocolate ou 6 2x2 3x3 de dois.

Claro, as crianças estão esperando para obter tão grande como chocolate, você ajuda pequena Hi calcular o comprimento máximo de um lado é quanto?

entrada

A primeira linha contém dois inteiros N e K. (1 <= N, K < = 100000)
As seguintes linhas N contém dois números inteiros Hi e WI. (1 <= Oi, Wi < = 100000)
de entrada para garantir que cada estudante, pelo menos, 1x1 em um chocolate pode ser obtido.

exportação

corte saída para fora de um quadrado de máxima de chocolate lado comprimento possível.

pensamento

E em frente desta questão é muito semelhante, e o tamanho do intervalo gama de chocolate é [1, max], do comprimento do lado do intervalo de chocolate durante dois minutos, se a
cal condição determinação (médio)> = k, borda isto é, podem ser separados comprimento médio chocolate é maior do que as crianças k, então você pode ser capaz de colocar alguns pontos mais chocolate.

código

#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
typedef long long LL;
const int N = 100010;
int num[N][2];
int n,k;
LL cal(int dat)
{
    LL sum = 0;
    for(int i = 0; i < n;i++)
    {
        int x = num[i][0]/dat;
        int y = num[i][1]/dat;
        sum +=  x * y;
        if(sum >= k)
            break;
    }
    return sum;
}
int main(void)
{
    scanf("%d %d", &n,&k);
    int ma = 0;               
    for(int i = 0; i < n;i++)
    {
        scanf("%d %d",&num[i][0],&num[i][1]);
        ma = max(ma,min(num[i][0], num[i][1]));//取所有巧克力中宽的最大值
    }
    int l = 1,r = ma;            
    while(l < r)
    {
        int mid = (l + r + 1) >> 1;
        if(cal(mid) >= k)
            l = mid;
        else
            r = mid - 1;
    }
    printf("%d",l);
    return 0;
}

pit encontrado

Inicialmente não identificou a faixa de fronteira, eu acho que é um direito de todo o chocolate deve ser um comprimento lateral mínimo de, porque se você quer usar cada pedaço de chocolate, então, certamente, todos olhando para o lado comprimento mínimo, mas, na verdade, um número de comprimento de lado pequena de chocolate pode fazer coisa. Isto foi encontrado após a apresentação, ou pensamento mal.

soma quatro praças

E quatro teorema quadrado, também conhecido como teorema de Lagrange:
Cada número inteiro positivo pode ser representado como um inteiro se positiva a 4 e a praça.
0 se incluído, ele pode ser representado assim como o quadrado do número 4 e.

Por exemplo:
5 + 2 = 0 ^ 0 ^ 1 ^ 2 + 2 + 2 ^ 2
7 = 1 ^ 1 ^ 2 + 2 + 1 + 2 ^ 2 ^ 2
(^ símbolo indica a potência média)

Para um dado número inteiro positivo, e pode haver representação quadrado múltipla.
O número reivindicação 4 Ordenar:
0 <= A <= B <= C <= D
e de todos os possíveis representações por a, b, c, d é uma chave primária em ordem ascendente, a primeira representação da saída final

entrada de programa é um número inteiro positivo de N (N <5000000)
saídas reivindicação quatro número inteiro não negativo, em ordem crescente, separados por espaços em branco

ideias:

Comecei a sair para pensar binário sobre isso, eu não queria sair, um pouco de pensamento por um momento para enumerar, mas o tempo sentimento para ler a solução para um problema, como segue:
1. Em primeiro lugar calcular a complexidade de tempo de enumeração: \ (\ sqrt {5 * 10 ^ 6 = 2240} \)
estimado para a complexidade de tempo ciclo triplo é o ( \ (10 ^. 9 \) ), aparentemente expirou (na verdade, porque a maior parte da N, b são pequenos, a maior parte do dados não irá expirar);

2. Então, para melhorar a enumeração, a abordagem geral é usar o espaço para o tempo . Neste problema:

  • C e d pode primeiro enumeração, o \ (C ^ 2 + d ^ 2 \) valores de C, D armazenado para baixo (armazenamento sequencial, de hash)
  • Enumerando a, b, computação \ (n-t = - ^ A ^ 2 B-2 \) , ou que o binário de hash para determinar se o t foi armazenado.
  • Se t existir, a saída direta.

Método 1 de hash

Uso \ (C ^ 2 + d ^ 2 \) valores directamente como uma função hash, pode notar-se que vários métodos podem constituir um valor, mas mantendo apenas o primeiro, porque a primeira lexicograficamente menor.

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 5000010;
int num[N][2];
int n;
int main(void)
{
    scanf("%d",&n);
    int m = 0;
    for(int c = 0; c * c <= n;c++ )
        for(int d = c;c * c + d * d <= n;d++)
        {
            int tmp = c*c + d*d;
            if(num[tmp][0] == 0 && num[tmp][1] == 0) //在哈希数组还未赋值的情况下,才允许赋值
            {
                num[tmp][0] = c;
                num[tmp][1] = d;
            }
        }
    for(int a = 0;a * a <= n;a++)
        for(int b = a; a * a + b * b <= n;b++)
        {
            int t = n - a * a - b * b;
            if(t == 0 || (num[t][0] != 0 || num[t][1] != 0))   //判断t是否存在,存在则直接输出a b c d
            {
                printf("%d %d %d %d",a,b,num[t][0],num[t][1]);
                return 0;
            }
        }
    return 0;
}

Método 2 minutos
semestre, então o primeiro passo é salvar \ (c ^ 2 + d ^ 2 \) valor, se repetido, como manter a ordem mínimo só dicionário, isso eu posso pensar de apenas transversal, olhar usos do programa de gângster que eu não sei C ++ sintaxe, adesivos, e para a aprendizagem.

//作者:yxc
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

const int N = 2500010;

struct Sum
{
    int s, c, d;
    bool operator< (const Sum &t)const
    {
        if (s != t.s) return s < t.s;
        if (c != t.c) return c < t.c;
        return d < t.d;
    }
}sum[N];

int n, m;

int main()
{
    cin >> n;

    for (int c = 0; c * c <= n; c ++ )
        for (int d = c; c * c + d * d <= n; d ++ )
            sum[m ++ ] = {c * c + d * d, c, d};   //不清楚这里是怎么处理有多种方法可以构成一个值的

    sort(sum, sum + m);

    for (int a = 0; a * a <= n; a ++ )
        for (int b = 0; a * a + b * b <= n; b ++ )
        {
            int t = n - a * a - b * b;
            int l = 0, r = m - 1;
			//二分
            while (l < r)
            {
                int mid = l + r >> 1;
                if (sum[mid].s >= t) r = mid;
                else l = mid + 1;
            }
            if (sum[l].s == t)
            {
                printf("%d %d %d %d\n", a, b, sum[l].c, sum[l].d);
                return 0;
            }
        }

    return 0;
}

Acho que você gosta

Origin www.cnblogs.com/zy200128/p/12594311.html
Recomendado
Clasificación