北京
E 题 Cats and Fish
题意:有n只猫m条鱼,然后每只猫吃鱼的速度不同,为ci,,,然后吃完当前鱼可以继续吃下一条,问经过x分钟后还剩下几只完整的鱼几只不完整的鱼。
思路:模拟,简单模拟这个过程就行,我们用一个bool数组来记录当前猫是否在吃鱼。遍历时间渐推,如果当前时间点吃完鱼,看是否还有鱼,还有时间,如果有的话,这只猫继续吃鱼。否则就是正在吃鱼时间到了。将vis改变即可。
#include
using namespace std;
int a[1005];
bool vis[1005];
int main(){
int n,m,x;
while(cin>>m>>n>>x){
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++) cin>>a[i];
if(x == 0){
cout<<"m 0"<<endl;
continue;
}
sort(a,a+n);//效率快的猫先吃鱼
for(int i=0;i<n;i++){
if(m>0){
//一开始几只猫在吃鱼
vis[i] = 1;//剩下的完整的鱼的数量
m--;
}
}
for(int i=1;i<=x;i++){
//枚举时间
for(int j=0;j<n;j++){
//枚举猫
if(i%a[j]==0 && m>0 &&i!=x) m--;//吃完一条鱼,还剩有鱼且还有时间,就吃下一条
else if(i%a[j]==0) vis[j]=0;//刚好吃完,那么停止吃鱼
}
}
int ans = 0;
for(int i=0;i<n;i++){
if(vis[i]) ans++;
}
cout<<m<<" "<<ans<<endl;
}
return 0;
}
F 题 Secret Poems
题意:就是打印由图一转变的图形,直接看样例就理解了。不过真的恶习哦,看了好一会还没看出规律是啥。就是把以前做过的一个蛇形矩阵变成了回型矩阵,不过还是好讨厌这样子的题目!!!先留个坑。
J 题 Pangu and Stones
题意:有一堆石头,每次你只能把L到R的石头合并成一堆,每一个石头都有一个时间,,每次需要合并的时间等于合并的石头总和,然后让你求合并这堆石头需要的最少的解决时间,如果没有解决方案就输出0。
思路:emmm…拿到题看着也不难,以前好像也遇见过这样子的题目。好的,我是废物,做了一个小时愣是想不到dp…
参考大佬思路:
状态转移:dp[I][j][k]表示从I到j的石头区间里分成k堆的情况
当k=1时,石头可以从L到R堆合并为1堆有dp[I][j][k]=max(dp[I][j][k],dp[I][j][d]+num[j]-num[I-1],这里的d我们表示堆数目(L<=d<=R)。num是前缀和的数组。
当k!=1时候,石头可以理解为一堆石头A与k-1堆石头B的合并,也就有dp[I][j][k]=max(dp[I][j][k],dp[I][e][1]+dp[e+1][j][k-1]),这里的e表示的是A和B的分界点,也就是普通的区间dp了,接下来的代码就比较清晰了。
#include
#include
#define mem(s,t) memset(s,t,sizeof(s))
using namespace std;
int dp[105][105][105];
int val[105];
int sum[105];
int main()
{
int n,l,r;
while(cin>>n>>l>>r)
{
mem(sum,0);
for(int i=1;i<=n;i++){
cin>>val[i];
sum[i]=sum[i-1]+val[i]; //求前缀和,方便计算
}
mem(dp,0x3f);
for(int i=1;i<=n;i++){
dp[i][i][1]=0;
}//初始化,每个石头之间没有合并所以他们花费的时间是0
for(int i=2;i<=n;i++){
//区间跨度
for(int j=1;j<=n;j++){
//起点
int e=i+j-1;
if(e>n)break;//终点不能大于n
for(int k=i;k>=1;k--){
//枚举堆数
if(k==1){
for(int z=l;z<=r;z++)
dp[j][e][k]=min(dp[j][e][k],dp[j][e][z]+sum[e]-sum[j-1]);
}else{
for(int z=j;z<e;z++)
dp[j][e][k]=min(dp[j][e][k],dp[j][z][1]+dp[z+1][e][k-1]);
}
}
}
}
if(dp[1][n][1]!=0x3f3f3f3f)cout<<dp[1][n][1]<<endl;
else cout<<0<<endl;
}
}
南宁
A-Abiyoyo
题意:属实手速签到
#include
using namespace std;
int main(){
int t,k;
scanf("%d",&t);
while(t--){
scanf("%d",&k);
for(int i=0;i<k;i++){
printf("Abiyoyo, Abiyoyo.\n");
}
printf("Abiyoyo, yo yoyo yo yoyo.\n");
printf("Abiyoyo, yo yoyo yo yoyo.\n");
}
return 0;
}
F
F 题 The Chosen One
题意:
有n个小孩排成一排,每次除去站在奇数位置上的小孩,问最后剩下哪一个
思路:自己动手看看模拟一下与样例,就会发现求得是小于n的2的最大次幂。
好像用py跟jave简单。
#include
using namespace std;
char anss[205][100],temp[205][100];
int jin=0,cnt=0,i,j,t,lang[200];
int main()
{
anss[0][0]='1';
for(i=1;i<=200;i++)
{
for(j=0;j<=cnt;j++)
{
anss[i][j]=((anss[i-1][j]-'0')*2+jin)%10+'0';
jin=((anss[i-1][j]-'0')*2+jin)/10;
}
while(jin){
anss[i][++cnt]=jin%10+'0';
jin=jin/10;
}
lang[i]=cnt;
}
for(i=1;i<=200;i++)
{
for(j=lang[i];j>=0;j--)
{
temp[i][lang[i]-j]=anss[i][j];
}
}
cin>>t;
while(t--)
{
char str[200];
cin>>str;
for(i=0;i<200;i++)
{
int flag1=0;
int flag2=0;
if(strlen(str)<lang[i+1]+1)
{
cout<<temp[i]<<endl;
break;
}
if(strlen(str)>lang[i]+1&&strlen(str)==lang[i+1]+1)
{
if(strcmp(temp[i+1],str)>0)
{
cout<<temp[i]<<endl;
break;
}
}
if(strlen(str)==lang[i]+1&&strlen(str)==lang[i+1]+1)
if(strcmp(temp[i],str)<=0&&strcmp(temp[i+1],str)>0)
{
cout<<temp[i]<<endl;
break;
}
}
}
}
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:入驻到云+社区