1. 程式人生 > >[Offer收割]程式設計練習賽79

[Offer收割]程式設計練習賽79

題目

題目1:

題意:

給定一個字串S,每次操作你可以將其中任意一個字元修改成其他任意字元,請你計算最少需要多少次操作,才能使得S中不存在兩個相鄰的相同字元。

思路:

從第二個字元往後,如果字元相同ans+1。因為s[i]的改變會對s[i-1],s[i+1]都產生影響,所以若s[i-1]與s[i]相同,改變s[i],那麼s[i+1]就不用考慮了。比如aaa,或aab這種情況,改變中間的a,因為有26個小寫字母,總能找到一個與兩邊字元不想關的字母,對於aaa,把中間的a可以換成b,c,d,e...,對於aab可以換成c,d,e,f...

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    string s;
    cin>>s;
    int ans=0;
    for(int i=1;s[i]!='\0';)
    {
        if(s[i]==s[i-1])
        {
            ans++;
            i++;
        }
        i++;
    }
    return 0;
}

題目2:

題意:

共有N名員工,編號為1~N,其中CEO的編號是1。除了CEO之外,每名員工都恰好有唯一的直接上司;N名員工形成了一個樹形結構。  
我們定義X的1級上司是他的直接上司,2級上司是他上司的上司,以此類推……  
N-1行每行包含一個整數,依次代表編號是2-N的員工的直接上司的編號。請你找出每名員工的D級上司是誰。

思路:

用vector建立樹形結構,v[i]表示的是以i為根的所有子節點。
考慮用dfs。dfs是一次性的搜尋樹的一整條枝。當該結點i相對於root的深度小於d的時候,直接ans[i]=-1,若深度大於d的時候,用path[]陣列記錄該條枝上的結點,ans[i]=深度-d;

注意:

程式中deep別忘了自減。

#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
vector<int>v[maxn];
int ans[maxn],path[maxn];
int deep,n,d;
void dfs(int q)
{
    if(deep<d) ans[q]=-1;
    else ans[q]=path[deep-d];
    path[deep++]=q;
    for(int i=0;i<v[q].size();i++)
        dfs(v[q][i]);
    deep--;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>d;
    for(int i=2;i<=n;i++)
    {
        int t;
        cin>>t;
        v[t].push_back(i);
    }
    deep=0;
    dfs(1);
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<endl;
    return 0;
}