目录
显示
第一次参加Topcoder的比赛233(主要是时间正合适)。
A. CinderellaGirls
数据范围实在太小了,模拟即可。
class CinderellaGirls
{
public:
int count(vector<int>talent,vector<int>skill)
{
int a[55],ans=0;
memset(a,0,sizeof(a));
int n=skill.size();
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(talent[i]>talent[j]&&skill[i]>skill[j])a[j]=1;
for(int i=0;i<n;i++)
if(!a[i])ans++;
return ans;
}
};
B. PAndPuns
如果能找到一个串 \(S\) 满足在给出的字符串中出现两次以上的条件,那么 \(S\) 的任意一个长度大于等于 \(2\) 的子串都会满足这个条件。
所以我们只用枚举长度为 \(2\) 的串进行检验即可。
class PAndPuns
{
public:
string check(string text)
{
int a[2505];
int len=text.length();
for(int i=1;i<len;i++)//字符串哈希
a[i]=(text[i-1]-'a')*26+(text[i]-'a');
for(int i=1;i<len;i++)
for(int j=i+2;j<len;j++)
if(a[i]==a[j])return "pun";
return "not a pun";
}
};
C. NewBanknote
询问的面额实在太大,传统的背包做法显然无法解决本题,搜索显然也要 TLE。
让我们从数据范围下手。我们可以枚举新钞票的使用张数,扣除这部分面额后贪心处理剩下的面额即可。
为什么这样是高效正确的呢?
可以证明新钞票的使用量不会超过 \(50000\) 张。原因很简单:如果新钞票面额超过 \(50000\),那使用 \(50000\) 张钞票早已经超过了要询问的面额上限;否则,\(50000\) 张新钞票还不如全部替换成 \(50000\) 的钞票,这样还能使解更优。
class NewBanknote
{
public:
vector<int> fewestPieces(int newBanknote, vector<int> amountsToPay)
{
int money[]={1,2,5,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000};
int t=amountsToPay.size();
vector<int> res;
for(int i=0;i<t;i++)
{
res.push_back(amountsToPay[i]);
for(int j=0;j<=50000;j++)
{
long long num=(long long)amountsToPay[i]-newBanknote*j;
if(num<0)break;
int cnt=j;
for(int k=14;k>=0;k--)
{
cnt+=num/money[k];
num%=money[k];
}
res[i]=min(res[i],cnt);
}
}
return res;
}
};