//暑假训练第一场,孤军奋斗,事后各种补题,(ps,说实话,时间点卡的不是很好,12点到17点, 没有午觉,大脑犯困, 各种困,各种累,再者,自己也慢慢的发现 精力开始不放在算法上了, 很多时候在做其他事, 别人在群里,或者是在哪里讨论题目的时候,不知何时,自己开始不自觉的远离, 开始闭塞门路,有点闭门造车, 所以AC的题目越来越少, 孤军奋斗难免要疼痛万分,)
也罢, 也不知道,我还能在坚持多久, 也许一个月? 也许一年? 也许几天? 8月份对于我来说是一个人生的转折点,如果可以,那么我将暂时放下这一切, 开始一段新的征途,2年后我们再会,但是不呢, 还是这样么?浑浑噩噩.,学的就这么忘了, 做过的就这么过去,到头了,白头如新, 啥也不会, 看起来都会,实则一个也不会, 没有后悔药,只能硬着头皮往前走,
走一步算一步?? 真就这么垃圾下去么. 真就荒废了.哎.//
问题 A: 公鸡打鸣
时间限制: 1 Sec 内存限制: 128 MB提交: 301 解决: 88
[ 提交][ 状态][ 讨论版]
题目描述
一天清晨,G1 开始先开始打鸣,响度值为 x,G2 听到 G1 的打鸣后也开始打鸣,响度值为 y。G1 和 G2 很想把它们打鸣声音的响度值调成一样。所以它们进行了 k 次协商,每一次协 商后就各自增加或减少一定的响度值再打鸣一次(打鸣的响度值不能小于 0)。G1 和 G2 生 性迟钝,它们不知道其实经过 s(s≤k)次协商后,打鸣声音的响度值已经相同了。
请编程帮 G1 和 G2 计算一下它们打鸣声音的响度值相同时最少经过了几次协商(即最 小的 s)?
注意:如果 x 一开始就等于 y,则不需要协商。
输入
第 1 行三个整数 x,y 和 k,分别表示 G1、G2 第一次打鸣时声音的响度值,共进行了 k次协商并调整打鸣声音的响度值。
接下来 k 行,每行包含 4 个整数 ai ,xi ,bi ,yi ,表示第 i 次协商 G1 增加(a i 等于 1)或减少(a i 等于-1)的响度值为 xi ,G2 增加(bi 等于 1)或减少(bi 等于-1)的响度值 yi 。
输出
样例输入
2 3 3
1 1 -1 0
-1 1 1 1
1 1 -1 1
样例输出
1
提示
在样例 1 中,G1 和 G2 第 1 次打鸣的响度值分别为 2 和 3,不相同。第 1 次协商 G1 增加 1,G2 减少 0,响度值分别为 3 和 3,所以经过 1 次协商后它们两个打鸣的响度值已经相同。经过 3 次协商时,它们的声音也能调成一样,但至少需要 1 次协商就可以了。
#include <stdio.h>
#include <string.h>
const int N=101000;
int main()
{
int x,y, k;
int a[N],b[N],c[N],d[N];
scanf("%d %d %d",&x,&y,&k);
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
int flag=0;
for(int i=1;i<=k;i++)
{
scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
}
if(x==y)
{
flag=1;
printf("0\n");
}
for(int i=1;i<=k;i++)
{
x+=a[i]*b[i];
y+=c[i]*d[i];
if(x<0)
x=0;
if(y<0)
y=0;
if(x==y)
{
printf("%d\n",i);
flag=1;
break;
}
}
if(!flag)
printf("-1\n");
}
return 0;
}
问题 B: 拯救小鸡
时间限制: 1 Sec 内存限制: 128 MB提交: 82 解决: 40
[ 提交][ 状态][ 讨论版]
题目描述
鸡国国王为了保护鸡国中的小鸡,决定派出鸡国警察(鸡国有无穷多个警察)来巡逻。
每个警察巡逻的时间长度都为 t 秒。当老鹰来袭击的时刻至少要有 x 名警察才能抵御老鹰的袭击。另外国王派遣警察有两个原则:
(1)每个时刻最多只能派遣一名警察。在第 0 秒时刻及第 0 秒之前的时刻(鸡国有负数时刻)也可以事先准备派遣警察,但每个时刻最多也只能派遣一名警察。
(2)延迟 1 秒执行巡逻任务。第 i 秒时刻派遣的警察,在第 i+1 到 i+t 秒时刻执行巡逻任务。
为帮助国王节省开支,请帮忙计算至少需要派遣多少名警察才能保证鸡国小鸡不被老鹰抓走?
输入
第 1 行输入三个整数 n,t,x,分别表示老鹰总共袭击次数,每个警察巡逻的时间长度为,以及某个时刻能抵挡住老鹰袭击的最少警察数量。
第 2 行 n 个严格升序排列的正整数 t i (1≤i≤n),表示第 t i 秒时刻老鹰会发动袭击。
输出
样例输入
3 3 3
2 3 4
样例输出
5
思路: 枚举时间轴, 找未重复的点
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
const int N =10000;
typedef long long ll;
/* 思路:
枚举时间轴, 找需要添加的时间点个数;
*/
ll a[N];
int vis[N];
int main()
{
int n,t,x;
ll ans;
while(cin>>n>>t>>x)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
cin>>a[i];
ans=0;
if(t<x)
{
cout<<"-1"<<endl;
continue;
}
for(int i=0;i<n;i++)
{
for(int j=1;j<=x;j++)
{
int temp=a[i]-t+j;
if(!vis[temp])
{
vis[temp]=1;
ans++;
}
}
}
cout<<ans<<endl;
}
return 0;
}
问题 C: 母鸡下蛋
时间限制: 1 Sec 内存限制: 128 MB提交: 261 解决: 61
[ 提交][ 状态][ 讨论版]
题目描述
鸡国专供下蛋的 n 个鸡窝呈一字排列在鸡国的“下蛋中心”,从左到右依次编号为 1 到n。每个鸡窝都有一个最大可下蛋的量,其中第 i 个鸡窝的最大可下蛋量为 ci 。有时候由于MGMG 产量实在太大而无法在一个鸡窝中下完所有的蛋,不得不转移到隔壁的鸡窝继续下蛋,如果隔壁的鸡窝还是不能让它下完所有的蛋,则 MGMG 继续转移,直到下完所有的蛋,或者向“下蛋中心”管理员投诉“鸡窝数量实在太少了,我一只鸡的下蛋量都装不下!”。
为了节省转移时所耗费的体力,请你编程帮助 MGMG 找若干个连续的鸡窝(个数尽量少),让它能下完所有的蛋。
输入
第 1 行输入两个整数 n 和 t,表示“下蛋中心”有 n 个可供下蛋的鸡窝,MGMG 一次总共要下 t 个鸡蛋。
第 2 行 n 个正整数 ci (1≤i≤n),依次表示第 i 个鸡窝最大可下蛋量为 ci 个。
输出
样例输入
5 4
1 2 1 2 3
样例输出
2
思路,dp 类似最长子序列
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N =101000;
ll dp[N];
int main()
{
int n,t;
while(cin>>n>>t)
{
int x;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
cin>>x;
dp[i]=dp[i-1]+x;
}
if(dp[n]<t)
{
cout<<"Angry"<<endl;
continue;
}
ll ans=N;
ll le=0,ri=n;
for(int i=1;i<=n;i++)
{
while(dp[i]-dp[le]>=t&&i>le)
{
if(i-le<ans)
{
ans=i-le;
}
le++;
}
}
cout<<ans<<endl;
}
return 0;
}
问题 D: 鸡国福利
时间限制: 1 Sec 内存限制: 128 MB提交: 132 解决: 10
[ 提交][ 状态][ 讨论版]
题目描述
互不相同,即来领过钱的鸡不能再来,否则将受到严厉的处罚。
但聪明的鸡国老百姓侦察后发现国王每天发的钱袋子里面装的钱数量是不一样的(同一天的相同),第 i 天发的每一袋钱为 a i 元。如果第 i 天来领钱的鸡领 1 袋钱,它可以获得ai 元的“鸡币”,如果它领 2 袋钱,则可以获得 2×ai 元“鸡币”,当然它也可以放弃,则第i 天的钱国王收回国库。
由于鸡国生活条件优越和鸡的贪念等原因,当第 i 天领钱的鸡同时满足以下两个条件时它才会感到幸福:
(1)领到的钱不能低于鸡国的平均收入 m 元。
(2)要跟它前面领了钱且感到幸福的鸡一样幸福或者更幸福。
仁慈的国王希望鸡国的每一只鸡都能感到幸福,请你帮国王规划一下在这 n 天中怎样给每一只发钱才能让最多的鸡感到幸福?
输入
第 1 行输入两个整数 n 和 m,分别表示发钱的天数(或理解为来领钱的鸡数)和鸡国的平均收入。
第 2 行 n 个正整数 ai (1≤i≤n),依次表示第 i 天发的一袋钱中的“鸡币”为 ai 元。。
输出
样例输入
2 1
2 1
样例输出
2
ing....
问题 E: chicken
时间限制: 1 Sec 内存限制: 128 MB提交: 134 解决: 92
[ 提交][ 状态][ 讨论版]
题目描述
一旦有顾客在其他超市找到更便宜的小鸡翅,NSC 超市将免费送给顾客 1000g 小 鸡翅。小 x 为了尽可能的省钱,走遍了各大超市,统计了小鸡翅的价格。NSC 的 工作人员通过不法手段盗取了这些资料。现在 NSC 的工作人员希望你能帮他们 定一个尽可能低的价格(1000g 小鸡翅的价格),使小 x 吃不到免费的小鸡翅。
输入
第二行一个正整数 N,表示其他超市的个数。
接下来 N 行,每行两个正整数 Xi(1 ≤ Xi ≤ 100) 和 Yi(1 ≤ Yi ≤ 1000), 表示在第 i 家超市,Yig 小鸡翅卖 Xi 元。
输出
样例输入
5 100
3
4 100
3 100
7 100
样例输出
30.00
#include <stdio.h>
int main()
{
int x,y,n;
scanf("%d %d",&x,&y);
scanf("%d",&n);
double a[10000],b[1000],c[1000];
double ans=10000;
double res=0;
for(int i=0;i<n;i++)
{
scanf("%lf %lf",&a[i],&b[i]);
c[i]=a[i]/b[i];
if(c[i]<ans)
{
ans=c[i];
}
}
printf("%.2f\n",ans*1000);
return 0;
}
问题 F: match
时间限制: 1 Sec 内存限制: 128 MB提交: 76 解决: 30
[ 提交][ 状态][ 讨论版]
题目描述
输入
输出
如果能找到,输出包含 3 行,第 i 行对应九宫格的第 i 行(最后一行行末要换行)。
如果有多种方案,请输出每种方案对应的字符串中字典序最前的一种(将行与行首尾相连,就可以得到一个字符串)。
样例输入
ANA
ANA
DAR
DAR
RAD
RAD
样例输出
DAR
ANA
RAD
#include <stdio.h>
#include <string.h>
#include <queue>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
string str[6];
void sorts()
{
for(int i=0;i<6;i++)
{
for(int j=0;j<5-i;j++)
{
string temp;
if(str[j]>str[j+1])
{
temp=str[j];
str[j]=str[j+1];
str[j+1]=temp;
}
}
}
}
bool judge(int x,int y,int z)
{
for(int i=0;i<6;i++)
{
int flag=1;
if(i!=x&&i!=y&&i!=z)
{
for(int j=0;j<3&&flag;j++)
{
if(str[i][0]==str[x][j]&&str[i][1]==str[y][j]&&str[i][2]==str[z][j])
flag=0;
}
if(flag)
return false;
}
}
return true;
}
int main()
{
for(int i=0;i<6;i++)
{
cin>>str[i];
}
sorts();
int flag=0;
for(int i=0;i<6&&!flag;i++)
for(int j=0;j<6&&!flag;j++)
for(int k=0;k<6&&!flag;k++)
{
if(i!=j&&i!=k&&j!=k)
{
if(judge(i,j,k))
{
cout<<str[i]<<endl;
cout<<str[j]<<endl;
cout<<str[k]<<endl;
flag=1;
}
}
}
if(!flag)
printf("0\n");
return 0;
}
问题 G: 【动态规划】cirs
时间限制: 1 Sec 内存限制: 128 MB提交: 128 解决: 49
[ 提交][ 状态][ 讨论版]
题目描述
输入
输出
样例输入
2
样例输出
2
提示
1 号点与 2 号点连接:2 种。
1 号点与 4 号点连接:1 种。
1 号点与 6 号点连接:2 种。
这种题: 2 5 14 基本上可以确定为卡特兰数
卡特兰数的几种求法
数组表示 数组表示c[i]=c[i-1]*(4*i-2)/(i+1); //不能超过大数模板
dp[1][1]=1; //可到40
for(i=2;i<40;i++)
for(j=1;j<=i;j++)
{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
dp[i][i]==//卡特兰数
a[0]=1;
a[1]=1;
a[2]=2;
for(inti=3;i<=n;i++)
{
for(int j=1;j<=i;j++)
a[i]=(a[i]+a[i-j]*a[j-1])%MOD;
}
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
typedef long long ll;
/*
卡特兰数
*/
const int N=101000;
const int MOD=100000007;
ll a[N];
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(a,0,sizeof(a));
a[0]=1;
a[1]=1;
a[2]=2;
for(int i=3;i<=n;i++)
{
for(int j=1;j<=i;j++)
a[i]=(a[i]+a[i-j]*a[j-1])%MOD;
}
printf("%lld\n",a[n]);
}
return 0;
}
问题 H: wtaxi
时间限制: 1 Sec 内存限制: 128 MB提交: 65 解决: 32
[ 提交][ 状态][ 讨论版]
题目描述
问题来了,一辆又一辆的出租车经过,但里面要么坐满了乘客,要么只剩下一两个座位,众 Oier 都觉得坐上去太亏了,小 x 也是这么想的。
假设 N 位 Oier 准备拼车,此时为 0 时刻,从校门到目的地需要支付给出租车师傅 D 元(按车次算,不管里面坐了多少 Oier),假如 S 分钟后恰能赶上比赛,那么 S 分钟后经过校门口的出租车自然可以忽略不计了。现在给出在这 S 分钟当中经过校门的所有的 K 辆出租车先后到达校门口的时间 Ti 及里面剩余的座位 Zi(1 <= Zi <= 4),Oier 可以选择上车几个人(不能超过),当然,也可以选择上 0 个人,那就是不坐这辆车。
俗话说,时间就是金钱,这里小 x 把每个 Oier 在校门等待出租车的分钟数等同于花了相同多的钱(例如小 x 等待了 20 分钟,那相当于他额外花了 20 元钱)。
在保证所有 Oier 都能在比赛开始前到达比赛地点的情况下,聪明的你能计算出他们最少需要花多少元钱么?
输入
接着 K 行,表示第 i 辆出租车在第 Ti 分钟到达校门,其空余的座位数为 Zi(时间按照先后顺序)。
N <= 100,K <= 100,D <= 100,S <= 100,1 <= Zi <= 4,1<= T(i) <= T(i+1) <= S
输出
则输出一个整数,代表他们最少需要花的钱(单位:元),否则请输出“impossible”。
样例输入
2 2 10 5
1 1
2 2
样例输出
14
dp,
#include <stdio.h>
#include <string.h>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
const int inf= 1<<29;
using namespace std;
void init(int *p)
{
for(int i=0;i<250;i++)
p[i]=inf;
}
int dp[250],pre[250];
int main()
{
init(dp);
init(pre);
int n,k,d,s;
while(cin>>n>>k>>d>>s)
{
dp[0]=0;
int t,z;
while(k--)
{
cin>>t>>z;
memcpy(pre,dp,sizeof(dp));
for(int i=0;i<=n;i++)// 人
{
for(int j=0;j<=z;j++)// 车
{
dp[i]=min(dp[i],pre[i-j]+d+j*t);
}
}
}
if(dp[n]!=inf)
printf("%d\n",dp[n]);
else
printf("impossible\n");
}
return 0;
}
问题 I: 【分治】化装晚会
时间限制: 1 Sec 内存限制: 64 MB提交: 175 解决: 76
[ 提交][ 状态][ 讨论版]
题目描述
万圣节又到了!FJ打算带他的奶牛去参加化装晚会,但是,FJ只做了一套能容下两头总长不超过S (1≤S≤1000000)的奶牛恐怖服装。FJ养了N(2≤N≤20000)头按1--N顺序编号的奶牛,编号为i的奶牛的长度为L_i(1≤L_i≤1000000)。如果两头奶牛的总长度不超过S,那么她们就能穿下这套服装。
FJ想知道,如果他想选择两头不同的奶牛来穿这套衣服,一共有多少种满足条件的方案。
输入
第1行是2个整数:N和S;
第2~N+l行每行一个整数:L_i。
输出
1个整数,表示FJ可选择的所有方案数。注意奶牛顺序不同的两种方案是被视为相同的。
样例输入
4 6
3
5
2
1
样例输出
4
提示
样例说明:4种选择分别为:奶牛1和奶牛3;奶牛l和奶牛4;奶牛2和奶牛4;奶牛3和奶牛4。
先排序,然后二分查找,
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf=1<<29;
ll a[20010],s,n;
ll find(int b,int c)
{
int l = b,hi = n+1;
while(l+1 < hi)
{
int mid =(l + hi)/2;
if(a[mid] <= c)
l = mid;
else
hi = mid;
}
return l-b;
}
int main()
{
ll i,ans=0;
scanf("%d%d",&n,&s);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
a[0]=-1;
a[n+1]=inf;
for(i=1;i<=n;i++)
{
ans+=find(i,s-a[i]);
}
printf("%lld",ans);
return 0;
}
问题 J: 【搜索】泡泡龙
时间限制: 1 Sec 内存限制: 64 MB提交: 160 解决: 65
[ 提交][ 状态][ 讨论版]
题目描述
这是一个简化版的网络游戏:在一个N×N方块构成的棋盘中,每个方块均涂上红、黄、蓝、绿(记为l、2、3、4)中的一种颜色,游戏者可以在最底行任意找一个方块,用鼠标双击这个方块,于是该方块及与之相邻(即在上、下、左、右四个方向上有公共边)的所有的同色方块均被消掉,而因下方失去支持的方块将会自由落下填补空位。样例中给出一个4×4的棋盘样例,当游戏者双击最底层左边第二个方块后,将会形成输出结果的布局。
你的任务是编写一个泡泡龙模拟程序,对于给定的一个初始棋盘,计算游戏者双击最底层某个方块后棋盘的布局将会如何。
输入
第1行有两个正整数N和M(I≤M≤N≤I00),其中N表示棋盘的规模,而M则表示游戏者将双击最底层从左边数起的第M个方块。接下来的N行每行有N个l~4的整数组成,表示一个初始的棋盘,同一行相邻两个数之间用一个空格隔开。
输出
N行,每行用N个数给出游戏结束后棋盘的布局,没有方块的格子用0表示,同一行相邻两个数之间也用一个空格分开。每行末尾有空格
样例输入
4 2
1 2 3 4
4 2 4 4
3 4 4 3
1 4 4 3
样例输出
1 0 0 0
4 0 0 0
3 2 0 3
1 2 3 3
提示
这道搜索确实确实让我很上头, 我直接四个方向搜索, 我觉着个思路是对的, 但就是过不了;
AC代码:
#include <stdio.h>
#include <string.h>
int maps[100][100];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int temp,n,m;
void find()
{
int i,j,k;
for(i=n;i>=1;i--)
{
for(j=1;j<=n;j++)
{
if(maps[i][j]==0)
{
for(k=i;k>=1;k--)
{
if(maps[k][j])
{
maps[i][j]=maps[k][j];
maps[k][j]=0;
break;
}
}
}
}
}
}
void dfs(int x,int y)
{
for(int i=0;i<4;i++)
{
int px=x+dir[i][0];
int py=y+dir[i][1];
if(px<1||px>n||py<1||py>n)
continue;
if(maps[px][py]==temp)
{
maps[px][py]=0;
dfs(px,py);
}
}
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
memset(maps,0,sizeof(maps));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
scanf("%d",&maps[i][j]);
}
temp=maps[n][m];
dfs(n,m);
maps[n][m]=0;
find();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",maps[i][j]);
}
printf("\n");
}
}
return 0;
}
未AC 代码:
#include <stdio.h>
#include <string.h>
int maps[100][100];
int n,m;
int temp;
int find(int x,int y)
{
int k=0;
for(int i=x;i>=1;i--)
{
if(maps[i][y]!=0)
{
k=maps[i][y];
maps[i][y]=0;
break;
}
}
return k;
}
void dfs(int x,int y)
{
if(maps[x-1][y]==temp)
{
maps[x][y]=0;
dfs(x-1,y);
}
if(maps[x][y-1]==temp)
{
maps[x][y]=0;
dfs(x,y-1);
}
if(maps[x][y+1]==temp)
{
maps[x][y]=0;
dfs(x,y+1);
}
if(maps[x+1][y]==temp)
{
maps[x][y]=0;
dfs(x+1,y);
}
maps[x][y]=0;
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&maps[i][j]);
temp=maps[n][m];
dfs(n,m);
maps[n][m]=0;
int k;
for(int i=n;i>=1;i--)
{
for(int j=n;j>=1;j--)
{
if(maps[j][i]==0)
{
k=find(j-1,i);
maps[j][i]=k;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",maps[i][j]);
}
printf("\n");
}
return 0;
}