AtCoder Beginner Contest 082

来源:互联网 发布:最好背单词软件 编辑:程序博客网 时间:2024/06/05 10:41

B - Two Anagrams
题意:给两个字符串a,b,每个字符串中字符的位置可以自由改变,问是否存在一种排列使a的字典序小于b的字典序。
题解:贪心,a从小往大排,b从大往小排,看是否存在a

    #include<bits/stdc++.h>    using namespace std;    typedef long long ll;    typedef long double db;    typedef pair<int,int> pii;    typedef vector<int> vi;    #define de(x) cout << #x << "=" << x << endl    #define rep(i,a,b) for(int i=a;i<(b);++i)    #define all(x) (x).begin(),(x).end()    #define sz(x) (int)(x).size()    #define mp make_pair    #define pb push_back    #define fi first    #define se second    #define lb(x) (x&-(x))    const int N = 101010;    char s1[200],s2[200];    int s1len,s2len;    int judge()    {        int minlen=min(s1len,s2len);        for(int i=0;i<minlen;i++)        {            if(s1[i]<s2[i])            {                return 1;            }            else if(s1[i]==s2[i])            continue;            else return 0;          }        if(s1len<s2len)        return 1;        else return 0;    }    bool cmp1(char a,char b)    {        return a<b;    }    bool cmp2(char a,char b)    {        return a>b;    }    int main(){        scanf("%s",s1);        scanf("%s",s2);         s1len=strlen(s1);        s2len=strlen(s2);           sort(s1,s1+s1len,cmp1);        sort(s2,s2+s2len,cmp2);    //  printf("%s\n",s1);    //  printf("%s\n",s2);        if(judge()) cout<<"Yes"<<endl;        else cout<<"No"<<endl;        return 0;    }

C

题意:给出一个序列 要使这个序列中所有的数满足ai出现ai次,最少需要删除几个数。
思路:如果ai大于他的出现次数aicnt,就减去aicnt个数;
如果ai小于他的出现次数aicnt,就减去ai个数。
对每种数用map存一下,然后计减去的数的和即可。

    #include<bits/stdc++.h>    using namespace std;    typedef long long ll;    typedef long double db;    typedef pair<int,int> pii;    typedef vector<int> vi;    #define de(x) cout << #x << "=" << x << endl    #define rep(i,a,b) for(int i=a;i<(b);++i)    #define all(x) (x).begin(),(x).end()    #define sz(x) (int)(x).size()    #define mp make_pair    #define pb push_back    #define fi first    #define se second    #define lb(x) (x&-(x))    const int N = 101010;    int main(){        map<int,int> m1;        int n,tmp,cnt=0;        cin>>n;        for(int i=0;i<n;i++)        {        scanf("%d",&tmp);        m1[tmp]++;        }        map<int,int>::iterator it;        for(it=m1.begin();it!=m1.end();it++)        {            if(it->first!=it->second)            {                if(it->first < it->second)                cnt+=it->second-it->first;                else                cnt+=it->second;            }        }        cout<<cnt<<endl;        return 0;    }

D
题意:一个机器人站在0,0点,方向朝向X轴正方向。给出一个操作序列 由F和T组成。如果是T 机器人可以转90度(方向随意),如果是F,就向对应方向前进一格。给出一个长度<=8000的操作序列和一个最终位置(x,y),询问这个位置是否能到达。
思路:把序列拆成x轴和Y轴上的两个数组,对XY轴的移动分别考虑。对于每个轴上的序列,即考虑:一个序列a1,a2,a3,…,an 通过加减运算得到目标值x。
对于这个子问题,我用dfs,最后果然TLE,水不过去了= =
正解用了类似的DP【i】表示i点可不可以到达。因为和的范围为【-8000,8000】,所以DP开16000+就够了。每次加入一个ai,考虑最多16000个dp[i]是否可以转移到。这样就从O(2^m)降低到了O(n*m).16000*8000还够。
以后状态空间有限的时候可以标记每个空间的状态解决问题。

    #include<bits/stdc++.h>    using namespace std;    typedef long long ll;    typedef long double db;    typedef pair<int,int> pii;    typedef vector<int> vi;    #define de(x) cout << #x << "=" << x << endl    #define rep(i,a,b) for(int i=a;i<(b);++i)    #define all(x) (x).begin(),(x).end()    #define sz(x) (int)(x).size()    #define mp make_pair    #define pb push_back    #define fi first    #define se second    #define lb(x) (x&-(x))    const int N = 101010;    int dp[2][17000];     int main(){        string s;        cin>>s;        int x,y;        cin>>x>>y;        vector<int> list[2];        int isrow=1,sum=0;        for(int i=0;i<s.length();i++)        {            char c=s[i];            if(c=='F')            sum++;            else if(c=='T')            {                list[isrow].pb(sum);                sum=0;                isrow=(isrow+1)%2;            }        }        list[isrow].pb(sum);    //  for(int i=0;i<list[0].size();i++)cout<<list[0][i]<<" ";cout<<endl;    //  for(int i=0;i<list[1].size();i++)cout<<list[1][i]<<" ";cout<<endl;          dp[0][8500]=1;//0点         dp[1][8500]=1;//0点         for(int ff=0;ff<2;ff++)        {            for(int i=0;i<list[ff].size();i++)            {                int x=list[ff][i];                int temp[17000];                memset(temp,0,sizeof(temp));                for(int j=0;j<17000;j++)//+-8000                {                    if(dp[ff][j]==1)                    {                        if(i==0&&ff==1)                        temp[j+x]=1;                        else                        {                            temp[j+x]=1;                            temp[j-x]=1;                        }                    }                 }                memcpy(dp[ff],temp,sizeof(temp));             }        }        if(dp[0][y+8500]&&dp[1][x+8500])        cout<<"Yes"<<endl;        else         cout<<"No"<<endl;        return 0;    }
原创粉丝点击