codeforces #215 div2前四題

果7發表於2013-11-29

其實這套題目不難,D題自己想也能想到那一塊,只是對stl用法還沒有那麼熟。。


第一題,水題

AC程式碼:

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

int a[102];

int main()
{
    int n,d,i,p;
    int ans;
    while(~scanf("%d%d",&n,&d))
    {
        ans=0;
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        scanf("%d",&p);

        if(p<=n)
        {
            for(i=0;i<=p-1;i++)
            {
                ans+=a[i];
            }
            printf("%d\n",ans);
        }
        else
        {
            for(i=0;i<n;i++)
            {
                ans+=a[i];
            }
            p-=n;
            ans-=d*p;
            printf("%d\n",ans);
        }
    }
    return 0;
}

就是這個水題,竟然當時把題目理解成最大了,還去叉別人的程式碼。。坑。。


第二題,水題

AC程式碼:

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

int a[100005];
map<int,int> mq;
int ans[100005];

int main()
{
    int i,n,m,t;
    while(cin>>n>>m)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        mq.clear();

        ans[n]=1;
        mq[a[n]]=1;
        for(i=n-1;i>=1;i--)
        {
            if(mq[a[i]])
            {
                ans[i]=ans[i+1];
            }
            else
            {
                mq[a[i]]=1;
                ans[i]=ans[i+1]+1;
            }
        }

        for(i=1;i<=m;i++)
        {
            scanf("%d",&t);
            printf("%d\n",ans[t]);
        }
    }
    return 0;
}


第三題,還算是比較有意思,只是題目有點難懂而已。

有一個字串,只由xyz字元組成。給m個詢問,每個詢問限定一個子串,該字串可以任意順序排列,如果存在一個排列,其中所有三個字元大小的子串都是由"zyx", "xzy", "yxz"中的一個字串組成的,則返回“”YES“,否則返回”NO“,如果字串不足三個,返回”YES“。

思路:其實就是統計子串中x,y,z的個數,符合要求的情況下,x,y,z個數中,最大的個數和最小的差不會超過一個。


當然我是慢慢找規律,先搞一個串xzyxzyxzy,然後兩邊不斷剝掉,統計個數即可。

AC程式碼:

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

char a[100005];
int dpx[100005];
int dpy[100005];
int dpz[100005];

int main()
{
    int len,i,m,l,r;
    while(~scanf("%s",a+1))
    {
        len=strlen(a+1);
        dpx[0]=dpy[0]=dpz[0]=0;
        for(i=1;i<=len;i++)
        {
            dpx[i]=dpx[i-1];
            dpy[i]=dpy[i-1];
            dpz[i]=dpz[i-1];
            if(a[i]=='x') dpx[i]++;
            if(a[i]=='y') dpy[i]++;
            if(a[i]=='z') dpz[i]++;
        }

        scanf("%d",&m);
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&l,&r);
            int xx,yy,zz;
            xx=dpx[r]-dpx[l-1];
            yy=dpy[r]-dpy[l-1];
            zz=dpz[r]-dpz[l-1];

            if(xx+yy+zz<3) puts("YES");  //
            else if(xx==yy&&yy==zz) puts("YES");  //0 0
            else if(yy==zz&&xx==yy-1) puts("YES");  //0 1
            else if(yy==xx&&zz==yy+1) puts("YES");  //0 2
            else if(xx==yy&&zz==yy-1) puts("YES"); //1 0
            else if(xx==zz&&yy==xx+1) puts("YES");  //1 1
            else if(yy==zz&&xx==yy+1) puts("YES");
            else if(xx==zz&&yy==xx-1) puts("YES");
            else
                puts("NO");
        }
    }
    return 0;
}


第四題,

B. Sereja ans Anagrams
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Sereja has two sequences a and b and number p. Sequence a consists of n integers a1, a2, ..., an. Similarly, sequence b consists ofm integers b1, b2, ..., bm. As usual, Sereja studies the sequences he has. Today he wants to find the number of positions q (q + (m - 1)·p ≤ nq ≥ 1), such that sequence b can be obtained from sequence aq, aq + p, aq + 2p, ..., aq + (m - 1)p by rearranging elements.

Sereja needs to rush to the gym, so he asked to find all the described positions of q.

Input

The first line contains three integers nm and p (1 ≤ n, m ≤ 2·105, 1 ≤ p ≤ 2·105). The next line contains n integers a1a2...an (1 ≤ ai ≤ 109). The next line contains m integers b1b2...bm (1 ≤ bi ≤ 109).

Output

In the first line print the number of valid qs. In the second line, print the valid values in the increasing order.

Sample test(s)
input
5 3 1
1 2 3 2 1
1 2 3
output
2
1 3
input
6 3 2
1 3 2 2 3 1
1 2 3
output
2
1 2


題意:給兩個陣列a和b,找出a中所有可能的q (q + (m - 1)·p ≤ n; q ≥ 1)

使得序列aq, aq + p, aq + 2p, ..., aq + (m - 1)p,能夠由陣列b改變值的順序排列而成。

解題思路:先根據%p分組,然後對組內進行處理,移動的時候可以使用兩個指標,

l和r不斷右移。用mq記錄b中每個數值能夠使用的次數,當存在滿足的情況時,

mq中所有的數值都正好使用完,一組之內之後的情況需要減掉序列最前面的一個值的

使用,加上序列之後新增加的值,並記錄當前狀態的滿足情況。


題目地址:B. Sereja ans Anagrams


AC程式碼:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int maxn=2e5+5;

map<int,int> mq;
vector<int> ans;
int a[maxn],b[maxn];

int main()
{
    long long n,m,p,i,j;
    while(cin>>n>>m>>p)
    {
        ans.clear();
        for(i=1;i<=n;i++) scanf("%d",&a[i]);
        for(i=1;i<=m;i++) scanf("%d",&b[i]);
        for(i=1;i<=p&&(i+(m-1)*p)<=n;i++)
        {
            mq.clear();
            for(j=1;j<=m;j++) mq[b[j]]++;  //先把b的元素種類和個數都儲存起來
            int step=0;
            for(j=i;;j+=p)
            {
                if(step==m) break;
                mq[a[j]]--;
                if(mq[a[j]]==0) mq.erase(a[j]);
                step++;
            }

            int l,r;     //用兩個指標對一個組的進行遍歷
            l=i,r=l+m*p;
            if(mq.size()==0) ans.push_back(l);
            while(1)
            {
                if(r>n) break;
                mq[a[l]]++,mq[a[r]]--;
                if(mq[a[r]]==0) mq.erase(a[r]);
                if(mq[a[l]]==0) mq.erase(a[l]);
                l+=p,r+=p;
                if(mq.size()==0) ans.push_back(l);
            }
        }

        sort(ans.begin(),ans.end());
        printf("%d\n",ans.size());
        for(i=0;i<ans.size();i++)
        {
            if(i)   printf(" ");
            printf("%d", ans[i]);
        }
        cout<<endl;
    }
    return 0;
}



相關文章