1. 程式人生 > >Codeforces Round #479 (Div. 3)解題報告

Codeforces Round #479 (Div. 3)解題報告

ive 操作規則 false iostream 數組 pre equal sort 報告

題目鏈接:  http://codeforces.com/contest/977  

A. Wrong Subtraction

題意

給定一個數x,求n次操作輸出。操作規則:10的倍數則除10,否則減1

直接寫,手速題,沒啥好說的

B. Two-gram

題意

求出現次數最多的連續兩個字符

還是簽到題,我居然很麻煩地用了map,= =算了,思路暢通都無所謂了

技術分享圖片
#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string
> #include<map> using namespace std; int main() { char a[100],s[5],ss[5]; int n; while(cin>>n) { cin>>a; map<string,int>mp; int MAX=-1; for(int i=0;i<strlen(a)-1;i++) { s[0]=a[i]; s[1]=a[i+1]; mp[s]
++; //cout<<s<<endl; if(mp[s]>MAX) MAX=mp[s],ss[0]=a[i],ss[1]=a[i+1]; } cout<<ss[0]<<ss[1]<<endl; } return 0; }
View Code

C. Less or Equal

題意

給一串數組,是否找到一個數x,找到k個數字<=x,找到輸出x,不能輸出-1。

第二組,要找到兩個數字,排序後出現1,3,3,會出現三個數字小於等於3,所以不能找到。

註意下k==0的時候就好了,沒啥好說的

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int a[maxn];
int main()
{
    int m,k;
    while(cin>>m>>k)
    {
        for(int i=0;i<m;i++)
            cin>>a[i];
        sort(a,a+m);
        if(k==0)
        {
            if(a[0]==1) puts("-1");
            else cout<<a[0]-1<<endl;
        }
        else if(k==m) cout<<a[k-1]<<endl;
        else
        {
            if(a[k-1]==a[k]) puts("-1");
            else cout<<a[k-1]<<endl;
        }
    }
    return 0;
}

D. Divide by three, multiply by two

題意

直接看樣例吧 4 8 6 3 12 9 把這個序列排成一個這樣的序列, 前一位是後一位數的一半或者3倍,所以排序後是這樣 9 3 6 12 4 8

dfs或者直接雙重for循環都可以,不過賽後看到個數學思路的題解,覺得很有靈性= =

直接按對3有更多約數的多少來排(前一位是後一位的3倍),有相同個則從小到大(也就是前一位是後一位數的一半)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#define ll long long
using namespace std;
const int maxm=2e5+10;
const int maxn=1e5+10;

ll a[105];
ll s(ll num)
{
    ll cnt=0;
    while(num%3==0)
    {
        cnt++;
        num/=3;
    }
    return cnt;
}
bool cmp(ll x,ll y)
{
    if(s(x)!=s(y))
        return s(x)>s(y);
    else return x<y;
}
int main()
{
    int n;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
            cin>>a[i];
        sort(a,a+n,cmp);
        for(int i=0;i<n;i++)
            printf("%lld%c",a[i],i==n-1?\n: );
    }
}

E. Cyclic Components

題意

給定點的個數和各條邊,問有多少個環

既然是環,一個點就會對應兩次啊,直接並查集啊,巴拉巴拉,水水水就過去了

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int pre[maxn],edg[maxn],cnt;
struct node
{
    int u,v;
}a[maxn];
void iint()
{
    for(int i=0;i<maxn;i++)  pre[i]=i;
}
int ffind(int x)
{
    if(x==pre[x])  return x;
    return pre[x]=ffind(pre[x]);
}
void join(int x,int y)
{
    x=ffind(x),y=ffind(y);
    if(x!=y)  pre[x]=y;
    else cnt++;
}
int main()
{
    int m,n;
    while(cin>>m>>n)
    {
        iint();
        memset(edg,0,sizeof(edg));
        for(int i=0;i<n;i++)
        {
            cin>>a[i].u>>a[i].v;
            edg[a[i].u]++;
            edg[a[i].v]++;
        }
        cnt=0;
        for(int i=0;i<m;i++)
        {
            if(edg[a[i].u]==2&&edg[a[i].v]==2)
                join(a[i].u,a[i].v);
        }
        cout<<cnt<<endl;
    }
    return 0;
}

F. Consecutive Subsequence

題意

給你一個數組找出最長的遞增子序列的長度以及下標位置。

例如:  第一組樣例 3 3 4 7 5 6 8

    最長的子序列為3 4 5 6,長度為4。

    下標為1 3 5 6或2 3 5 6

覺得dp才是正解,貼個別人的http://www.bubuko.com/infodetail-2595514.html

可是比賽時候不知道為什麽被我map玄學給過了2333

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int a[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n,tmp;
    while(cin>>n)
    {
        map<int,int>mp;
        int max_pos=-1,Max=-1;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            mp[a[i]]=mp[a[i]-1]+1;
            if(mp[a[i]]>Max)    Max=mp[a[i]],tmp=a[i],max_pos=i;
        }
        int u=tmp-Max+1;
        cout<<Max<<endl;
        bool f=true;
        for(int i=1;i<=max_pos;i++)
        {
            if(a[i]==u)
            {
                if(f) cout<<i,f=false;
                else cout<<" "<<i;
                u++;
            }
        }
        cout<<endl;
    }
    return 0;
}

Codeforces Round #479 (Div. 3)解題報告