A 吐泡泡
时间限制:C/C++ 1秒,其他语言2秒
64bit IO Format: %lld
题目描述
小鱼儿吐泡泡,嘟嘟嘟冒出来。小鱼儿会吐出两种泡泡:大泡泡"O",小泡泡"o"。
两个相邻的小泡泡会融成一个大泡泡,两个相邻的大泡泡会爆掉。
(是的你没看错,小气泡和大气泡不会产生任何变化的,原因我也不知道。)
例如:ooOOoooO经过一段时间以后会变成oO。
输入描述:
数据有多组,处理到文件结束。
每组输入包含一行仅有'O'与'o'组成的字符串。
输出描述:
每组输出仅包含一行,输出一行字符串代表小鱼儿吐出的泡泡经过融合以后所剩余的泡泡。
输入
ooOOoooO
输出
oO
说明
自左到右进行合并
备注:
对于100%的数据,
字符串的长度不超过100。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const int maxn = 111;
int cnt[maxn];
int main()
{
string s;
while(cin>>s){
int flag =1;
while(flag){
memset(cnt,0,sizeof cnt);
flag=0;
int now = s[0]=='O'?1:0;
string ss = "";
for(int i=1;i<s.length();i++){
if(now==1&&s[i]=='O'){
flag=1;
cnt[i-1]=cnt[i]=-1;
break;
}
else if(now==-1){
now = s[i]=='O'?1:0;
}else if(now==1&&s[i]=='o'){
now =0;
}else if(now==0&&s[i]=='O'){
now = 1;
}else if(now==0&&s[i]=='o'){
cnt[i-1]=1;
cnt[i]=-1;
flag=1;
break;
}
}
for(int i=0;i<s.length();i++){
if(cnt[i]==1) ss+='O';
if(cnt[i]==0) ss+=s[i];
}
s=ss;
}
cout<<s<<endl;
}
}
时间限制:C/C++ 1秒,其他语言2秒
64bit IO Format: %lld
题目描述
Taotao的电脑带不动绝地求生,所以taotao只能去玩pc版的荒野行动了,
和绝地求生一样,游戏人物本身可以携带一定重量m的物品,装备背包
之后可以多携带h(h为0代表没有装备背包)重量的东西。玩了几天
taotao发现了一个BUG,当装备背包之后,如果可携带重量没有满,就
可以拿一个任意重的东西。(解释看样例)有一天taotao空降到了一个
奇怪的岛上,岛上有n件装备,每个装备都有重量Wi和威力值Vi,但taotao
不认识这些装备,所以他来求助你,挑选威力最大的装备,帮助他吃鸡。
输入描述:
本题有多组输入(小于10),当n=0时结束输入。
第一行输入n,m,h。n,m,h为整数,并且0<=n,m,h<=100,
接下来n行,每行输入第i个物品的物品的重量Wi和威力值Vi。0<=Wi,Vi<=100.
输出描述:
输出最大威力值,每组输出一行。
输入
3 3 3 2 3 3 2 2 3 0
输出
8
说明
可携带的总重量为6,当拿了前两件装备,此时容量为5/6,还可以再拿第三件物品。
把bug拿的装备的容量变为1.遍历一次所有情况
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const LL maxn = 1111;
int dp[222];
int w[222];
int v[222];
int n,m,h;
int f()
{
memset(dp,0,sizeof dp);
int vv=h+m;
for(int i=1;i<=n;i++)
if(v[i]==0){
continue;
}else
for(int j=vv;j>=w[i];j--){
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
return dp[vv];
}
int main()
{
while(~scanf("%d",&n)&&n){
scanf("%d%d",&m,&h);
int sum = 0;
for(int i=1;i<=n;i++){
scanf("%d %d",&w[i],&v[i]);
if(w[i]==0) sum+=v[i],v[i]=0;
}
int ans = 0;
if(h!=0){
for(int i=1;i<=n;i++){
int temp=w[i];
w[i]=1;
ans=max(ans,f());
w[i]=temp;
}
printf("%d\n",ans+sum);
}else{
printf("%d\n",f()+sum);
}
}
}
C题:
链接:https://www.nowcoder.com/acm/contest/74/C
来源:牛客网
小仙女过生日啦,好多名人都来了,像是小金刚,凹凸曼,光头强啊。来了那么多人,小仙女羞涩的躲了起来。这时,空气中传来了一缕蛋糕的香气,小仙女再也顾不得羞涩了,冲了出来两眼冒绿光的看着(n边形)蛋糕,小仙女心想:emmmm。。。人好多啊,自己一个人吃不好啊。可是我想吃大份啊!!!怎么办怎么办!!!小G看到了这一幕,为了让小仙女不能开开心心的吃大的蛋糕,只能是沿着对角线切切(n-3)次,切成三角形,切成(n-2)块把最大的那一块给小仙女,现在想怎么才能让最大的那块蛋糕最小呢。
要注意的是这题min一定要设置为0x3f3f3f3f.不知道为什么。反之这次训练赛总有莫名其妙的wa点。体验极差。
#include <string>
#include <string.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <stdio.h>
using namespace std;
const int maxn = 200;
struct point
{
double x,y;
}p[maxn];
double dp[maxn][maxn];
int n;
double dis(int i,int j)
{
double x = p[i].x-p[j].x;
double y = p[i].y-p[j].y;
return sqrt(x*x+y*y);
}
double mul(int a,int b,int c)
{
double x = dis(a,b),y=dis(b,c),z=dis(a,c);
double p = x+y+z;
p/=2;
return sqrt(p*(p-x)*(p-y)*(p-z));
}
bool check(int a,int b,int c)
{
double pre = mul(a,b,c);
for(int i=1;i<=n;i++){
if(i==a||i==b||i==c) continue;
double now = mul(a,b,i)+mul(a,c,i)+mul(b,c,i);
if(fabs(now-pre)<1e-8) return false;
}
return true;
}
double dfs(int l,int r)
{
if(dp[l][r]>-1) return dp[l][r];
if(r-l<2) return 0;
if(r-l==2){
return mul(l,l+1,r);
}else{
double Min = 0x3f3f3f3f;//一定要是这个,不然wa到死。
for(int i=l+1;i<r;i++){
if(check(l,i,r)){
double Max = max(mul(l, i, r), max(dfs(i,r),dfs(l,i)));
Min = min(Min,Max);
}
}
return dp[l][r]=Min;
}
}
int main()
{
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
memset(dp,-1,sizeof dp);
printf("%.1lf\n",dfs(1,n));
}
return 0;
}
D YB要打炉石
时间限制:C/C++ 1秒,其他语言2秒
64bit IO Format: %lld
题目描述
Wozuinb非常喜欢打炉石传说,但是菜的不行,所以他决定打
竞技场来练练手。系统按顺序给出n张卡牌,每张卡牌都有自
己的使用消耗a[i],每次只给出一张,wozuinb可以选择或者
弃掉这张牌。每选择一张牌都会按选择顺序放在卡槽中,当
卡槽中放满30张即可组成一套套牌。Wozuinb希望自己的套牌的
消耗满足一个平滑的曲线,即30张卡牌都满足第i张卡牌的消耗
不小于第i-1张(i>1)。请你帮助wozuinb看一看,这些卡牌能不
能组成想要的套牌,如果能组成输出“yes”,如果不能输出“no”。
输入描述:
第一行输入一个整数n,0<n<100。
第二行输入一行数字a[i],每个数字用空格隔开,代表第i张出现的卡牌的消耗。
输出描述:
输出一行,“yes”或“no”
输入
5 1 2 3 4 5
输出
no
不绝对的最长上升子序列。
while输入wa。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const LL maxn = 1111;
LL a[maxn];
LL cnt[maxn];
int main()
{
LL n ;
scanf("%lld",&n);
for(LL i=1;i<=n;i++)
scanf("%lld",&a[i]);
memset(cnt,0,sizeof cnt);
cnt[1]=a[1];
LL len = 1;
for(LL i=2;i<=n;i++){
if(a[i]>=cnt[len]){
cnt[++len]=a[i];
}else{
LL temp = upper_bound(cnt+1,cnt+1+len,a[i])-cnt;
cnt[temp]=a[i];
}
}
// printf("%lld\n",len);
if(len>=30){
printf("yes\n");
}else{
printf("no\n");
}
}
E 小G有一个大树
时间限制:C/C++ 1秒,其他语言2秒
64bit IO Format: %lld
题目描述
小G想要把自己家院子里的橘子树搬到家门口(QAQ。。就当小G是大力水手吧)
可是小G是个平衡性灰常灰常差的人,他想找到一个这个橘子树的平衡点。
怎么描述这棵树呢。。。就把它看成由一个个节点构成的树吧。结点数就
代表树重。
输入描述:
多组数据输入输出,
第一行包含一个整数n(3<=n<=1000)代表树的结点的个数
以下n-1行描述(1-n)节点间的连接关系。
输出描述:
输出两个个整数 x,num 分别代表树的平衡点,和删除平衡点后最大子树的结点数(如果结点数相同输出编号小的)。
输入
3 1 2 1 3
输出
1 1
根本看不懂题目。
#include <string>
#include <string.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <stdio.h>
using namespace std;
const int mod = 100000000;
const int maxn = 1<<14;
vector<int>G[maxn];
int num[maxn];
int ansx,ansnum;
int n;
//
//树的平衡点? 我没学过
void dfs(int u,int pre)
{
num[u]=1;
int m=0;
for(int i=0;i<G[u].size();i++){
int to = G[u][i];
if(to==pre) continue;
dfs(to,u);
num[u]+=num[to];
m=max(m,num[to]);
}
m=max(m,n-num[u]);
if(m<ansnum){
ansnum=m;
ansx=u;
}else if(m==ansnum){
ansx=min(ansx,u);
}
}
int main()
{
while(~scanf("%d",&n)){
ansnum=0x3f3f3f3f;
for(int i=1;i<=n;i++) G[i].clear(),num[i]=0;
for(int i=1;i<n;i++){
int l,r;scanf("%d %d",&l,&r);
G[l].push_back(r);
G[r].push_back(l);
}
dfs(1,0);
printf("%d %d\n",ansx,ansnum);
}
return 0;
}
F 德玛西亚万岁
时间限制:C/C++ 1秒,其他语言2秒
64bit IO Format: %lld
题目描述
输入描述:
输入包含多组测试数据;
每组数据的第一行包含2个整数n和m (n <= 12, m <= 12 ),之间用空格隔开;
接下来的n行,每行m个数,表示n*m的比尔吉沃特领土。
输出描述:
输出一个整数n代表安排应用的方法。
(答案取膜100000000)
输入
3 3 1 1 1 0 1 1 1 0 0
输出
24
状态DP入门题
#include <string>
#include <string.h>
#include <iostream>
#include <queue>
#include <math.h>
#include <stdio.h>
using namespace std;
const int mod = 100000000;
int kind[5000];
int dp[5000][20];
int mp[22];
int n,m;
int num=0;
void dfs()
{
for(int i=0;i<=((1<<m)-1);i++){
if((i&(i<<1))==0){
kind[++num]=i;
}
}
}
int main()
{
while(~scanf("%d %d",&n,&m)){
memset(mp,0,sizeof mp);
for(int i=1;i<=n;i++){
for(int j=1,x;j<=m;j++){
scanf("%d",&x);
if(x==0) mp[i]+=1<<(j-1);
}
}
memset(dp,0,sizeof dp);
num=0;
dfs();
for(int j=1;j<=num;j++){
int x=kind[j];
if((x&mp[1])==0){
dp[j][1]=1;
}
}
for(int i=2;i<=n;i++){
for(int j=1;j<=num;j++){
int x=kind[j];
for(int k=1;k<=num;k++){
int y=kind[k];
if((x&y)>0) continue;
if((y&mp[i])>0) continue;
(dp[k][i]+=dp[j][i-1])%=mod;
}
}
}
int ans=0;
for(int i=1;i<=num;i++){
(ans+=dp[i][n])%=mod;
}
printf("%d\n",ans);
}
return 0;
}
G 送分了QAQ
时间限制:C/C++ 1秒,其他语言2秒
64bit IO Format: %lld
题目描述
输入描述:
多组输入输出;
输入的都是整数对n、m(0<n≤m<1000000),
如果遇到都是0的整数对,则输入结束。
输出描述:
对于每次的输入
输出全部令人讨厌的数的个数
输入
1 100 0 0
输出
20
数位DP。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const int maxn = 111;
int num[11];
int dp[11][3][11];
int dfs(int pos,int sta,bool limit,int pre)
{
if(pos==0&&(sta==1||sta==2)) return 1;
if(pos==0) return 0;
if(pre!=-1&&!limit&&dp[pos][sta][pre]!=-1) return dp[pos][sta][pre];
int up=limit?num[pos]:9;
int temp=0;
for(int i=0;i<=up;i++){
if(pre==3&&i==8){
temp+=dfs(pos-1,1,limit&&i==num[pos],i);
}else if(i==4){
temp+=dfs(pos-1,1,limit&&i==num[pos],i);
}else{
temp+=dfs(pos-1,sta,limit&&i==num[pos],i);
}
}
if(!limit&&pre!=-1) dp[pos][sta][pre]=temp;
return temp;
}
int f(int x)
{
int cnt=0;
while(x){
num[++cnt]=x%10;
x=x/10;
}
return dfs(cnt,0,true,-1);
}
int main()
{
int n,m;
memset(dp,-1,sizeof dp);
while(scanf("%d %d",&n,&m)){
if(n+m==0) break;
printf("%d\n",f(m)-f(n-1));
}
}