数字游戏
(number)
输入文件名:number.in
输出文件名:number.out
共 20 个测试点,每个测试点 5 分
每个测试点限时 1 秒,运行内存上限 256MB
问题描述
小 K 同学向小 P 同学发送了一个长度为 88 的 01 字符串 来玩数字游戏,小 P 同学想要知道字符串中究竟有多少个 11。
注意:01 字符串为每一个字符是 00 或者 11 的字符串,如“101”(不含双引号)为一个长度为 33 的 01 字符串。
输入格式
输入文件名为 number.in。
输入文件只有一行,一个长度为 88 的 01 字符串 ss。
输出格式
输出文件名为 number.out。
输出文件只有一行,包含一个整数,即 01 字符串中字符 11 的个数。
样例 1 输入
1
00010100
样例 1 输出
1
2
样例 1 解释
该 01 字符串中有 22 个字符 11。
样例 2 输入
1
11111111
样例 2 输出
1
8
样例 2 解释
该 01 字符串中有 88 个字符 11。
样例 3 输入
1
01010101
样例 3 输出
1
4
数据范围
对于 2020% 的数据,保证输入的字符全部为 00。
对于 100100% 的数据,输入只可能包含字符 00 和字符 11,字符串长度固定为 88。
题解:
#include
using namespace std;
int main()
{
//freopen(“number.in”,“r”,stdin);
//freopen(“number.out”,“w”,stdout);
char c1,c2,c3,c4,c5,c6,c7,c8;
scanf("%c%c%c%c%c%c%c%c",&c1,&c2,&c3,&c4,&c5,&c6,&c7,&c8);
int ans=0;
if(c1==‘1’) ans++;
if(c2==‘1’) ans++;
if(c3==‘1’) ans++;
if(c4==‘1’) ans++;
if(c5==‘1’) ans++;
if(c6==‘1’) ans++;
if(c7==‘1’) ans++;
if(c8==‘1’) ans++;
printf("%d",ans);
return 0;
}
公交换乘(transfer)
输入文件名:transfer.in
输出文件名:transfer.out
共 20 个测试点,每个测试点 5 分
每个测试点限时 1 秒,运行内存上限 256MB
题目描述
著名旅游城市 B 市为了鼓励大家采用公共交通方式出行,推出了一种地铁换乘公交车的优惠方案:
在搭乘一次地铁后可以获得一张优惠票,有效期为 4545 分钟,在有效期内可以消耗这张优惠票,免费搭乘一次票价不超过地铁票价的公交车。在有效期内指开始乘公交车的时间与开始乘地铁的时间之差小于等于 4545 分钟,即
t_{bus}-t_{subway} \le 45t
bus
−t
subway
≤45
搭乘地铁获得的优惠票可以累积,即可以连续搭乘若干次地铁后再连续使用优惠票搭乘公交车。
搭乘公交车时,如果可以使用优惠票一定会使用优惠票;如果有多张优惠票满足条件,则优先消耗获得最早的优惠票。
现在你得到了小轩最近的公共交通出行记录,你能帮他算算他的花费吗?
输入格式
输入文件名为 transfer.in。
输入文件的第一行包含一个正整数 nn,代表乘车记录的数量。
接下来的 nn 行,每行包含 33 个整数,相邻两数之间以一个空格分隔。第 ii 行的第 11 个整数代表第 ii 条记录乘坐的交通工具,00 代表地铁,11 代表公交车;第 22 个整数代表第 ii 条记录乘车的票价 price_iprice
i
;第三个整数代表第 ii 条记录开始乘车的时间 t_it
i
(距 00 时刻的分钟数)。
我们保证出行记录是按照开始乘车的时间顺序给出的,且不会有两次乘车记录出现在同一分钟。
输出格式
输出文件名为 transfer.out。
输出文件有一行,包含一个正整数,代表小轩出行的总花费。
样例 1 输入
1
6
2
0 10 3
3
1 5 46
4
0 12 50
5
1 3 96
6
0 5 110
7
1 6 135
样例 1 输出
1
36
样例 1 解释
第一条记录,在第 3 分钟花费 1010 元乘坐地铁。
第二条记录,在第 46 分钟乘坐公交车,可以使用第一条记录中乘坐地铁获得的优惠票,因此没有花费。
第三条记录,在第 50 分种花费 1212 元乘坐地铁。
第四条记录,在第 96 分钟乘坐公交车,由于距离第三条记录中乘坐地铁已超过 45 分钟,所以优惠票已失效,花费 33 元乘坐公交车。
第五条记录,在第 110 分钟花费 55 元乘坐地铁。
第六条记录,在第 135 分钟乘坐公交车,由于此时手中只有第五条记录中乘坐地铁获得的优惠票有效,而本次公交车的票价为 66 元,高于第五条记录中地铁的票价 55 元, 所以不能使用优惠票,花费 66 元乘坐公交车。
总共花费 3636 元。
样例 2 输入
1
6
2
0 5 1
3
0 20 16
4
0 7 23
5
1 18 31
6
1 4 38
7
1 7 68
样例 2 输出
1
32
样例 2 解释
第一条记录,在第 1 分钟花费 55 元乘坐地铁。
第二条记录,在第 16 分钟花费 2020 元乘坐地铁。
第三条记录,在第 23 分钟花费 77 元乘坐地铁。
第四条记录,在第 31 分钟乘坐公交车,此时只有第二条记录中乘坐的地铁票价高于本次公交车票价,所以使用第二条记录中乘坐地铁获得的优惠票。
第五条记录,在第 38 分钟乘坐公交车,此时第一条和第三条记录中乘坐地铁获得的优惠票都可以使用,使用获得最早的优惠票,即第一条记录中乘坐地铁获得的优惠票。
第六条记录,在第 68 分钟乘坐公交车,使用第三条记录中乘坐地铁获得的优惠票。
总共花费 3232 元。
数据范围
对于 3030% 的数据,n \le 1000n≤1000,t_i \le 10^6t
题解:
#include
using namespace std;
struct Ticket
{
int price;
int last;
bool used;
};
Ticket tic[100001];
int main()
{
//freopen(“transfer.in”,“r”,stdin);
//freopen(“transfer.out”,“w”,stdout);
bool bus;
int t,pri,x=1,y=0;
int n,sum=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>bus>>pri>>t;
if(!bus)
{
y++;
tic[y].last=t+45;
tic[y].price=pri;
tic[y].used=false;
sum+=pri;
}
else
{
bool can=false;
int newx=x;
for(int j=x;j<=y;j++)
{
if(tic[j].last
newx=j;
continue;
}
if((tic[j].price>=pri)&&(!tic[j].used))
{
can=true;
tic[j].used=true;
break;
}
}
x=newx;
sum+=(!can)*pri;
}
}
cout<
}
纪念品(souvenir)
输入文件名:souvenir.in
输出文件名:souvenir.out
共 20 个测试点,每个测试点 5 分
每个测试点限时 1 秒,运行内存上限 256MB
问题描述
小伟突然获得一种超能力,他知道未来 TT 天 NN 种纪念品每天的价格。某个纪念品的价格是指购买一个该纪念品所需的金币数量,以及卖出一个该纪念品换回的金币数量。
每天,小伟可以进行以下两种交易 无限次:
任选一个纪念品,若手上有足够金币,以当日价格购买该纪念品;
卖出持有的任意一个纪念品,以当日价格换回金币。
每天卖出纪念品换回的金币可以立即用于购买纪念品,当日购买的纪念品也可以当日卖出换回金币。当然,一直持有纪念品也是可以的。
TT 天之后,小伟的超能力消失。因此他一定会在第 TT 天卖出所有纪念品换回金币。
小伟现在有 MM 枚金币,他想要在超能力消失后拥有尽可能多的金币。
输入格式
输入文件名为 souvenir.in。
第一行包含三个正整数 T,N,MT,N,M,相邻两数之间以一个空格分开,分别代表未来天数 TT,纪念品数量 NN,小伟现在拥有的金币数量 MM。
接下来 TT 行,每行包含 NN 个正整数,相邻两数之间以一个空格分隔。第 ii 行的 NN 个正整数分别为 P_{i,1}, P_{i,2}, \ldots \ldots ,P_{i,N}P
i,1
,P
i,2
,……,P
i,N
,其中 P_{i,j}P
i,j
表示第 ii 天第 jj 种纪念品的价格。
输出格式
输出文件名为 souvenir.out。
输出仅一行,包含一个正整数,表示小伟在超能力消失后最多能拥有的金币数量。
输入样例 1
1
6 1 100
2
50
3
20
4
25
5
20
6
25
7
50
输出样例 1
1
305
输入输出样例 1 说明
最佳策略是:
第二天花光所有 100100 枚金币买入 55 个纪念品 1;
第三天卖出 55 个纪念品 1,获得金币 125125 枚;
第四天买入 66 个纪念品 1,剩余 55 枚金币;
第六天必须卖出所有纪念品换回 300300 枚金币,第四天剩余 55 枚金币,共 305305 枚金币。
超能力消失后,小伟最多拥有 305305 枚金币。
输入样例 2
1
3 3 100
2
10 20 15
3
15 17 13
4
15 25 16
输出样例 2
1
217
输入输出样例 2 说明
最佳策略是:
第一天花光所有金币买入 1010 个纪念品 1;
第二天卖出全部纪念品 1 得到 150150 枚金币并买入 88 个纪念品 2 和 11 个纪念品 3,剩余 11 枚金币;
第三天必须卖出所有纪念品换回 216216 枚金币,第二天剩余 11 枚金币,共 217217 枚金币。
超能力消失后,小伟最多拥有 217217 枚金币。
数据规模与约定
对于 1010% 的数据,T = 1T=1。
对于 3030% 的数据,T \leq 4T≤4,N \leq 4N≤4,M \leq 100M≤100,所有价格 10 \leq P_{i,j} \leq 100 10≤P
i,j ≤100。
对于 1515% 的数据,T \leq 100T≤100,N = 1N=1。
对于 1515% 的数据,T = 2T=2,N \leq 100 N≤100。
对于 100100% 的数据,T \leq 100T≤100,N \leq 100N≤100,M \leq 10^3M≤10
3,所有价格 1 \leq P_{i,j} \leq 10^4 1≤P i,j ≤104 ,数据保证任意时刻,小明手上的金币数不可能超过 10^4104。
题解:
#include
#include
#define gc ch=getchar()
#define max(a,b) a>b?a:b
using namespace std;
template void read(T &s){
s=0;T f=1;char gc;
while(ch<‘0’||ch>‘9’){if(ch==’-’)f=-1;gc;}
while(ch>=‘0’&&ch<=‘9’){s=s10+ch-‘0’;gc;}
s=f;
}
template void put(T s){
if(s<0) putchar(’-’),s=-s;
if(s>9) put(s/10);
putchar(s%10+‘0’);
}
int t,n,m,a[105][105],f[10005];
int main(){
//freopen(“souvenir.in”,“r”,stdin);
//freopen(“souvenir.out”,“w”,stdout);
read(t),read(n),read(m);
for(int i=1;i<=t;++i)
for(int j=1;j<=n;++j) read(a[i][j]);
for(int i=1;i
for(int j=1;j<=n;++j)
for(int k=a[i][j];k<=m;++k)
f[k]=max(f[k],f[k-a[i][j]]+a[i+1][j]-a[i][j]);
m=max(f[m]+m,m);
}
put(m);
return 0;
}
加工零件(work)
输入文件名:work.in
输出文件名:work.out
共 20 个测试点,每个测试点 5 分
每个测试点限时 1 秒,运行内存上限 256MB
问题描述
凯凯的工厂正在有条不紊地生产一种神奇的零件,神奇的零件的生产过程自然也很神奇。工厂里有 nn 位工人,工人们从 11 ~ nn 编号,某些工人之间存在双向的零件传送带。保证每两名工人之间最多只存在一条传送带。
如果 xx 号工人想生产一个被加工到第 L(L > 1)L(L>1) 阶段的零件,则所有与 xx 号工人有传送带直接相连的工人,都需要生产一个被加工到第 L-1L−1 阶段的零件(但 xx 号工人自己无需生产第 L-1L−1 阶段的零件)。
如果 xx 号工人想生产一个被加工到第 11 阶段的零件,则所有与 xx 号工人有传送带直接相连的工人,都需要为 xx 号工人提供一个原材料。
轩轩是 11 号工人。现在给出 qq 张工单,第 ii 张工单表示编号为 a_ia
i
的工人想生产一个第 L_iL
i
阶段的零件。轩轩想知道对于每张工单,他是否需要给别人提供原材料。他知道聪明的你一定可以帮他计算出来!
输入格式
输入文件名为 work.in。
第一行三个正整数 n,mn,m 和 qq,分别表示工人的数目、传送带的数目和工单的数目。
接下来 mm 行,每行两个正整数 uu 和 vv,表示编号为 uu 和 vv 的工人之间存在一条零件传送带。保证 u \neq vu
=v。
接下来 qq 行,每行两个正整数 aa 和 LL,表示编号为 aa 的工人想生产一个第 LL 阶段的零件。
输出格式
输出文件名为 work.out。
共 qq 行,每行一个字符串“Yes”或者“No”。如果按照第 ii 张工单生产,需要编号为 11 的轩轩提供原材料,则在第 ii 行输出“Yes”;否则在第 ii 行输出“No”。注意输出不含引号。
样例 1 输入
1
3 2 6
2
1 2
3
2 3
4
1 1
5
2 1
6
3 1
7
1 2
8
2 2
9
3 2
样例 1 输出
1
No
2
Yes
3
No
4
Yes
5
No
6
Yes
样例 1 解释
编号为 1 的工人想生产第 1 阶段的零件,需要编号为 2 的工人提供原材料。
编号为 2 的工人想生产第 1 阶段的零件,需要编号为 1 和 3 的工人提供原材料。
编号为 3 的工人想生产第 1 阶段的零件,需要编号为 2 的工人提供原材料。
编号为 1 的工人想生产第 2 阶段的零件,需要编号为 2 的工人生产第 1 阶段的零件,需要为编号 1 和 3 的工人提供原材料。
编号为 2 的工人想生产第 2 阶段的零件,需要编号为 1 和 3 的工人生产第 1 阶段的零件,他/她们都需要编号为 2 的工人提供原材料。
编号为 3 的工人想生产第 2 阶段的零件,需要编号为 2 的工人生产第 1 阶段的零件,需要编号为 1 和 3 的工人提供原材料。
样例 2 输入
1
5 5 5
2
1 2
3
2 3
4
3 4
5
4 5
6
1 5
7
1 1
8
1 2
9
1 3
10
1 4
11
1 5
样例 2 输出
1
No
2
Yes
3
No
4
Yes
5
Yes
样例 2 解释
编号为 1 的工人想生产第 1 阶段的零件,需要编号为 2 和 5 的工人提供原材料。
编号为 1 的工人想生产第 2 阶段的零件,需要编号为 2 和 5 的工人生产第 1 阶段的零件,需要编号为 1,3,41,3,4 的工人提供原材料。
编号为 1 的工人想生产第 3 阶段的零件,需要编号为 2 和 5 的工人生产第 2 阶段的零件,需要编号为 1,3,41,3,4 的工人生产第 1 阶段的零件,需要编号为 2,3,4,52,3,4,5 的工人提供 原材料。
编号为 1 的工人想生产第 4 阶段的零件,需要编号为 2 和 5 的工人生产第 3 阶段的零件,需要编号为 1,3,41,3,4 的工人生产第 2 阶段的零件,需要编号为 2,3,4,52,3,4,5 的工人生产第 1 阶段的零件,需要全部工人提供原材料。
编号为 1 的工人想生产第 5 阶段的零件,需要编号为 2 和 5 的工人生产第 4 阶段的零件,需要编号为 1,3,41,3,4 的工人生产第 3 阶段的零件,需要编号为 2,3,4,52,3,4,5 的工人生产 第 2 阶段的零件,需要全部工人生产第 1 阶段的零件,需要全部工人提供原材料。
题解:
#include
using namespace std;
const int nn=1e5+5;
bool inque[nn];
int Last[nn],Prev[nn<<1],Begin[nn<<1],End[nn<<1],cnt=0;
inline void make_line(int x,int y) {
cnt++;
Prev[cnt]=Last[x];
Last[x]=cnt;
Begin[cnt]=x;
End[cnt]=y;
return;
}
int dis[nn][2];
queue p;
inline void spfa(){
memset(dis,0x3f,sizeof(dis));
dis[1][0]=0;
p.push(1);
inque[1]=true;
while(!p.empty()){
int k=p.front();
p.pop();
inque[k]=false;
for(int i=Last[k];i;i=Prev[i]){
if(dis[End[i]][1]>dis[k][0]+1){
dis[End[i]][1]=dis[k][0]+1;
if(!inque[End[i]])
p.push(End[i]);
inque[End[i]]=true;
}
if(dis[End[i]][0]>dis[k][1]+1){
dis[End[i]][0]=dis[k][1]+1;
if (!inque[End[i]])
p.push(End[i]);
inque[End[i]] = true;
}
}
}
return;
}
int n,m,q;
int main(){
//freopen(“work.in”,“r”,stdin);
//freopen(“work.out”,“w”,stdout);
scanf("%d%d%d",&n,&m,&q);
int x,y;
bool flag=false;
while(m–){
scanf("%d%d",&x,&y);
make_line(x,y);
make_line(y,x);
if (x1||y1)
flag=true;
}
spfa();
while(q–){
scanf("%d%d",&x,&y);
if(x1&&!flag) {
puts(“No”);
continue;
}
if(dis[x][1]<=y&&y%21){
puts(“Yes”);
continue;
}
if (dis[x][0]<=y&&y%2==0){
puts(“Yes”);
continue;
}
puts(“No”);
}
return 0;
}
本人第一次写博客,请多指教。