B - Two Anagrams
题意:给两个字符串a,b,每个字符串中字符的位置可以自由改变,问是否存在一种排列使a的字典序小于b的字典序。
题解:贪心,a从小往大排,b从大往小排,看是否存在a
#include
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;iif(s1[i]return 1;
}
else if(s1[i]==s2[i])
continue;
else return 0;
}
if(s1lenreturn 1;
else return 0;
}
bool cmp1(char a,char b)
{
return abool 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"<else cout<<"No"<return 0;
}
C
题意:给出一个序列 要使这个序列中所有的数满足ai出现ai次,最少需要删除几个数。
思路:如果ai大于他的出现次数aicnt,就减去aicnt个数;
如果ai小于他的出现次数aicnt,就减去ai个数。
对每种数用map存一下,然后计减去的数的和即可。
#include
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;iscanf("%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<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
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;ichar 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
// for(int i=0;i
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"<else
cout<<"No"<return
0;
}