Problem A. Standing Ovation
题目说的是有许多观众,每个观众有一定的羞涩值,只有现场站起来鼓掌的人数达到该值才会站起来鼓掌,问最少添加多少羞涩值任意的人,才能使所有人都站起来鼓掌。
贪心模拟一下就好,添加的人默认让他们羞涩值为0,扫一遍,让加到刚好够就行。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <deque>
using namespace std;
char str[1010];
int main(){
freopen("A-large.in","r",stdin);
freopen("A-large.out","w",stdout);
int t;
cin>>t;
int cas=0;
while(t--){
cas++;
int MAX;
cin>>MAX;
scanf("%s",str);
int len=strlen(str);
int cnt=0;
int ans=0;
for(int i=0;i<len;i++){
str[i]-='0';
cnt+=str[i];
if(cnt<i+1){
int add = i+1-cnt;
cnt+=add;
ans+=add;
}
}
printf("Case #%d: %d\n",cas,ans);
}
return 0;
}
这个题很有意思。。说的是若干盘子上有一定量的食物,正常情况下,所有盘子上的食物每秒钟会减少1,或者你可以让某些秒变得特别,在特别的秒,盘子上的食物不会减少,但是你可以挑选一个有食物的盘子,移动部分或全部食物到另一个盘子上(空盘无限多)。目标是使所有食物尽快被吃完。
稍微分析一下,很容易得出这样一个结论,先分再吃,也就是说,早分一定不会比晚分差。然后很容易想到贪心去分割食物最多的盘子,分一半给空盘。其实这样是不对的。。比如只有一个食物为9的盘子,分成3,3,3比分成4,5要优。
我的解法是,首先只考虑只有一个盘子有食物的情况,dp预处理,dp(i,j)表示这个盘子有i个单位的食物,分为若干份,最大份食物量为j,至少需要多少次。
过了几天回来看了下,发现自己非常2B,直接分就行了。。为什么还要去dp。所以这个题就是枚举一下找出最小值。
然后就是贪心+枚举,先分再吃。枚举分的程度,即让所有盘子经过划分以后,食物最多的盘子不超过一个特定的值。详见代码。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <queue>
using namespace std;
const int maxn = 1001;
int p[maxn];
int dp[maxn][maxn];
int main(){
freopen("B-large.in","r",stdin);
freopen("B-large.out","w",stdout);
//dp预处理
for(int i=2;i<maxn;i++){
for(int j=1;j<i;j++){
dp[i][j]=1000;
for(int k=1;k<i;k++){
dp[i][j]=min(dp[i][j],dp[i-k][j]+dp[k][j]+1);
}
}
}
int t;
cin>>t;
for(int cas=1;cas<=t;cas++){
int d;
cin>>d;
int MAX=0;
for(int i=1;i<=d;i++){
scanf("%d",&p[i]);
MAX=max(MAX,p[i]);
}
int ans=MAX;
//枚举。即把所有食物量大于test的盘子分为若干份,使得不再出现食物量大于test的盘子
for(int test=1;test<=MAX;test++){
int tmp=0;
for(int i=1;i<=d;i++){
tmp+=dp[p[i]][test];
}
tmp+=test;
ans=min(ans,tmp);
}
printf("Case #%d: %d\n",cas,ans);
}
return 0;
}Problem C. Dijkstra
这个题我只暴力过了小数据,大数据没想清楚怎么做。贴一下暴力代码。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <queue>
using namespace std;
/*
1-1
i-2
j-3
k-4
*/
int tab[5][5]={
{ 0, 0, 0, 0, 0},
{ 0, 1, 2, 3, 4},
{ 0, 2,-1, 4,-3},
{ 0, 3,-4,-1, 2},
{ 0, 4, 3,-2,-1}
};
int calc(int a,int b){
bool flag=0;
if(a<0){
a=-a;
flag=!flag;
}
if(b<0){
b=-b;
flag=!flag;
}
int re=tab[a][b];
if(flag)re=-re;
return re;
}
char str[10010];
char re[10010][10010];
int main(){
freopen("C-small-attempt0.in","r",stdin);
freopen("C-small-attempt0.out","w",stdout);
int t;
cin>>t;
int cas=0;
while(t--){
cas++;
int l,x;
cin>>l>>x;
scanf("%s",str);
for(int i=0;i<l;i++){
if(str[i]=='i')str[i]=2;
else if(str[i]=='j')str[i]=3;
else str[i]=4;
}
for(int i=1;i<x;i++){
for(int j=0;j<l;j++){
str[i*l+j]=str[j];
}
}
int tot=l*x;
if(tot<3){
printf("Case #%d: NO\n",cas);
continue;
}
for(int i=0;i<tot;i++){
re[i][i]=str[i];
for(int j=i+1;j<tot;j++){
re[i][j]=calc(re[i][j-1],str[j]);
}
}
bool ok=false;
for(int i=0;i<tot-2;i++){
for(int j=tot-1;j>i+1;j--){
if(re[0][i]==2&&re[j][tot-1]==4&&re[i+1][j-1]==3){
ok=1;
}
}
}
if(ok){
printf("Case #%d: YES\n",cas);
}else{
printf("Case #%d: NO\n",cas);
}
}
return 0;
}Problem D. Ominous Omino
小数据其实就64中case,用脑子想一下打表交就可以了。大数据真心不会做Orz。
本文深入探讨了算法、技术领域的多个方面,包括前端、后端、移动开发、游戏开发、大数据等,提供了从基础知识到高级应用的详细解析。
1658

被折叠的 条评论
为什么被折叠?



