CodeForces 123A 構造 + YY

題意

題目鏈接
給一個字符串,然後對於這個字符串來說,他的素數p位置 * i (1=<p*i <= len)要等於p他本身,從新構造這個字符串,判斷是否有一種情況滿足這個條件

並查集什麼的沒用上
做法是暴力染色,統計出相同的位置的個數,
然後用貪心,按詞頻從大到小盡量匹配,剩餘的隨便分配即可
這個題還是比較噁心,儘量不要在這商量花費太多時間,但是對鍛鍊代碼能力還是挺不錯的

#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
#define out(x) cout<<#x<<": "<<x<<endl
const double eps(1e-8);
const int maxn=2100;
const long long maxint=-1u>>1;
const long long maxlong=maxint*maxint;
typedef long long lint;
#define maxnode 41000
#define sigma_size 26
int n, sum[maxn];
char s[maxn];
int f[maxn];
int num[300], g[maxn];

bool isprime(int x)
{
  for (int i=2; i*i<=x; i++)
    if (x%i==0) return false;
  return true;
}

void init()
{
    scanf("%s",s);
    n=strlen(s);
    for (int i=0; i<n; i++)
      num[s[i]]++;
}
struct node 
{
  int x,time; 
} a[maxn], b[maxn];

bool cmp(node a, node b)
{
  return a.time>b.time;
}

void work()
{
  memset(f,0,sizeof(f));
  for (int i=2; i<=n; i++)
    if (isprime(i)) {
      for (int k=i; k<=n; k+=i) 
      {
        if (f[k]) {
          int old=f[k];
          for (int x=1; x<=n; x++) 
            if (f[x]==old) f[x]=i;  
        }
        f[k]=i;
      }

    //  cout<<"--------"<<i<<endl;
     // for (int i=0; i<=n; i++)
       // cout<<i<<" "<<f[i]<<endl;
    }

  for (int i=1; i<=n; i++)
    sum[f[i]]++;  
  for (int i=0; i<=n; i++)
    a[i].x=i,a[i].time=sum[i];
  sort(a+1,a+n+1,cmp);


  //for (int i=0; i<=n; i++)
    //cout<<i<<" "<<f[i]<<endl;
  //for (int i=0; i<=n; i++)
    //cout<<a[i].x<<" "<<a[i].time<<endl;


  for (int i='a'; i<='z'; i++)
    b[i-'a'+1].x=i,b[i-'a'+1].time=num[i];
  sort(b+1,b+1+26,cmp);

  //for (int i=1; i<=26; i++)
    //cout<<(char)b[i].x<<" "<<b[i].time<<endl;


  bool flag=true;
  for (int i=1; i<=n; i++)
  {
    if (a[i].time==0) continue;
    int tmp=0;
    for (int j=1; j<=26; j++)
      if (b[j].time>=a[i].time && ((tmp==0) || (b[j].time>b[tmp].time))) 
        tmp=j;
    //cout<<i<<": "<<tmp<<endl;
    //out(a[i].time);
    //out(b[tmp].time);
    if (tmp==0) {
      flag=false;
      break;
    }
    g[a[i].x]=b[tmp].x;
    b[tmp].time-=a[i].time;
  }
  //for (int i=1; i<=26; i++)
    //cout<<(char)b[i].x<<" "<<b[i].time<<endl;


  if (!flag) {
    cout<<"NO"<<endl;
    return;
  } else cout<<"YES"<<endl; 

  char wjj[maxn];
  for (int i=0; i<n; i++)
  {
    if (f[i+1]!=0) {
      wjj[i]=g[f[i+1]];
  //    out(i);
    //  out(f[i]);
    //  out(g[f[i]]);
    } else 
    {
      for (int j=1; j<=26; j++)
        if (b[j].time>0) {
          wjj[i]=b[j].x;
          b[j].time--;
        }
   }
  }

  wjj[n]='\0';
  cout<<wjj<<endl;

}

int main()
{

  init();
  work();
  return 0;
}

參考

CodeForces 123A 並查集
codeforces 123A A. Prime Permutation(數論+構造)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章