oj1026: ugly number (priority queues, and to find the optimal solution)

Topics requirements
humble number is the number of prime factors only 2,3,5,7 four, in addition to other no longer contains
other prime factors.

Note 1 also considered the number of ugly before 20 numbers ugly is
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, ...;
the input
per line N, 1 <= N <= 5842, N is the end of the zero input.
the output
outputs the corresponding N-th ugly number.
the Sample the input
Raw
. 1
2
. 3
. 4
. 11
12 is
13 is
21 is
22 is
23 is
100
1000
5842
0
the Sample the Output
Raw
. 1
2
. 3
. 4
12 is
14
15
28
30
32
450
385 875
2000000000.
This question before, only to find out whether a conventional traverse divisible numbers equal to 0, always display the timeout. Recently I saw a vector, set, map and priority queue afterthought.
Very simple to do when the first pass, the number is a multiple of 2,3,5,7 ugly, as long as the minimum number of from 1 starts ugly, with a priority queue to keep all ugly number generated each time that the minimum number taken it can be multiplied by 2,3,5,7 natural next several ugly, because it is a priority queue, it can be arranged directly from small to large, doing so should be noted that the figures will be repeated, so remember to go heavy. Finally, just know that given a number, you can know the number of ugly on the location of the.
The complete code

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<set>
#include<queue>

using namespace std;
typedef long long LL;
const int num[4]={2,3,5,7};

int main()
{
  priority_queue<LL,vector<LL>,greater<LL> >pq;//从小到大的优先队列
  set<LL>s;//set
  int n=1,t;
  int a[5844];
  pq.push(1);//插入刚开始的1
  s.insert(1);
  for(int i=1; ;i++)
  {
    LL x=pq.top();pq.pop();
    if(i==n)
    {
      a[n]=x;
      n++;
      if(n==5843)
        break;
    }
    for(int j=0;j<4;j++)
    {
      LL x2=x*num[j];
      if(!s.count(x2))
      {
        s.insert(x2);
        pq.push(x2);//不断更新队列
      }
    }
  }
  while(cin>>t)
  {
    if(t==0)break;
     cout<<a[t]<<endl;
  }
	return 0;
}

Later, asked about the seniors cohort of knowledge, he said I do complicated. . .
Ideas can be used to find the optimal solution, first determine ans [1] = 1, there are four ways to 2,3,5,7 points ans [1], where will choose 2. So we can determine the second, third. . . .
This part of the code stickers

inline void init()
{
    ans[1] = 1;
    fill(p, p + 4, 1);//置1
    ll val;
    for(int i=2; i<=maxN; i++)
    {
        val = MIN_4(ans[p[0]] * 2LL, ans[p[1]] * 3LL, ans[p[2]] * 5LL, ans[p[3]] * 7LL);
        if(val == ans[p[0]] * 2LL) p[0]++;
        if(val == ans[p[1]] * 3LL) p[1]++;
        if(val == ans[p[2]] * 5LL) p[2]++;
        if(val == ans[p[3]] * 7LL) p[3]++;
        ans[i] = val;
    }
}
Published 38 original articles · won praise 27 · views 3170

Guess you like

Origin blog.csdn.net/qq_45891413/article/details/105188027