由于题目主人有隐私,不方便贴出题目
题目大意:
n串密码,然后k组输入,当输入的是其中一个密码的前面几位或者整串密码时,可以成功解锁。
思路:
做法1:
暴力存入set中,然后搜索即可。
代码:
#include<iostream>
#include<cstdio>
#include <string.h>
#include <map>
using namespace std;
#define ll long long
map<string,bool>m;
map<string,bool>::iterator it;
char a[13];
int main(){
int t;
cin>>t;
while(t--){
scanf("%s",a);
string num;
for(int i=0;i<strlen(a);i++){
num+=a[i];
it=m.find(num);
if(it==m.end())
m.insert(make_pair(num,1));
}
}
int b,o=1;
scanf("%d",&b);
while(b--){
string k;
cin>>k;
it=m.find(k);
printf("Case #%d:\n",o++);
if(it!= m.end()) printf("YES\n");
else printf("NO\n");
}
}
做法2:
字典树(模板题,详解请看 https://blog.csdn.net/qq_43333395/article/details/89289170 )
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int trie[400001][15],len,root,tot,sum[400001];
bool p;
int n,m;
char s[11];
void insert()
{
len=strlen(s);
root=0;
for(int i=0;i<len;i++)
{
int id=s[i]-'0';
if(!trie[root][id]) trie[root][id]=++tot;
sum[trie[root][id]]++;//前缀保存
root=trie[root][id];
}
}
int search()
{
root=0;
len=strlen(s);
for(int i=0;i<len;i++)
{
int id=s[i]-'0';
if(!trie[root][id]) return 0;
root=trie[root][id];
}//root经过此循环后变成前缀最后一个字母所在位置
return 1;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>s;
insert();
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
cin>>s;
printf("%d\n",search());
}
}
冰水挑战
Polar Bear Pitching helps you crystallize your message.
The stage could not be any cooler, and we mean literally:
a hole cut through the ice in the frozen Baltic Sea.
2050有一项很有挑战的活动 —— Polar Bear Pitching 。
体验人跳入冰水中讲述自己的恐惧,改变以及梦想。这是没有时间限制的演讲,就看你能在冰水中呆多久!
现在,我们要依次面对 n 个冰水挑战,每个挑战你都可以选择接受或不接受。接受第 i 个挑战会让你丧失 ai点体力,因为每个挑战所处的环境不同,如果你要挑战它,在挑战它之前你的体力 x 会变成 min(x,bi),当你完成这个挑战的时候,你的体力会变成 x−ai,体力任何时候不允许小于等于 0,无论你是否接受第 i 个挑战,在这个挑战结束以后你的体力都会增加 ci。
现在我们想知道最多可以完成多少个挑战。
Input
第一行一个正整数 T (T≤50) 表示数据组数。
接下来 T 组数据,每组第一行两个正整数 n,c (1≤n≤103,1≤c≤109),表示挑战的数量和初始体力,接下来 n 行,每行三个非负整数 ai,bi,ci(0≤ai,bi,ci≤109)。
Output
对于每组数据输出一行一个数,表示你最多能完成几个挑战。
Sample Input
2
3 10
1 2 0
4 8 3
6 10 1
2 1
1 1 1
1 1 1
Sample Output
2
0
暴力dfs哈哈
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
ll a[1005],b[1005],c[1005];
ll dp[1005][1005];
ll n,x;
int ans=0;
void dfs(int i,int j,ll x){
if(dp[i][j]>=x)
return;
dp[i][j]=x;
if(i==n+1){
ans=max(ans,j);
return;
}
if(min(x,b[i])-a[i]>0)
dfs(i+1,j+1,min(x,b[i])-a[i]+c[i]);
dfs(i+1,j,x+c[i]);
return;
}
int main(){
int t;
cin>>t;
while(t--){
ans=0;
memset(dp,-1,sizeof(dp));
scanf("%lld %lld",&n,&x);
for(int i=1;i<=n;i++){
scanf("%lld %lld %lld",&a[i],&b[i],&c[i]); }
dfs(1,0,x);
printf("%d\n",ans);
}
}
分宿舍
“那天TA说TA要来,于是我就来啦。
那天我说我要来,于是你就来啦。
TA看到了什么?
你又看到了什么?
我看到你们在一起,我是真的很happy:)
太阳在哪里啊?
就在早上七八点。
太阳在哪里啊?
就在云的栖息地!”
——2050主题曲
2050的线下活动吸引了很多心怀梦想的年轻人。
小伙们打算组团去参加。他们一共有 n+m+2k 个人,包括 n+k 个男生,m+k 个女生,其中 k 对男女生为异性情侣,现在他们要找房间住。房间有三种类型,双人间 a 元一间,三人间 b 元一间,这两种只能同性一起住。情侣间能住一对异性情侣,一间 c 元。除了情侣间以外,其他房间都可以不住满。
求最少花多少钱,能让小伙伴们都有地方住。
Input
第一行一个整数 T (1≤T≤50) 表示数据组数。
接下来 T 组数据,每组数据一行 6 个整数 n,m,k,a,b,c,其中 0≤n,m,k≤103,0≤a,b,c≤109。
Output
对于每组数据输出一行一个数,表示所有人住下来所需要的最小花费。
Sample Input
2
3 0 1 1 3 3
3 3 2 1 6 2
Sample Output
3
6
大佬说是dp或者直接考虑最优策略枚举。
考虑性价比分间,然后再考虑要不要拆开一个小的变成大的或者一个大的变成小的。
自己写了一个dp,不知道正确不正确。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll T,n,m,k,a,b,c;
ll dp[3005][3005][3];
int main(){
cin>>T;
while(T--){
ll sum=0;
scanf("%lld %lld %lld %lld %lld %lld",&n,&m,&k,&a,&b,&c);
int o=0;
if(a*3<=b*2&&a<=c) o=1; //优先考虑a
if(a*3>b*2&&b*2<c*3) o=2; //优先考虑b
if(a>c&&b*2>c*3) o=3; //优先考虑c
if(o==1){
sum+=(k/2)*a*2;
k=k%2;
}
if(o==2){
sum+=(k/3)*b*2;
k=k%3;
}
if(o==3){
sum+=k*c;
k=0;
}
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[n][m][k]=0;
for(int i=n;i<=n+3;i++){
for(int j=m;j<m+3;j++)
for(int l=k;l<=k+3;l++){
dp[i][j][l]=0;
}
}
for(int i=n;i>=0;i--){
for(int j=m;j>=0;j--){
for(int l=k;l>=0;l--){
if(dp[i][j][l]>dp[i+2][j][l]+a){ //男买a
dp[i][j][l]=dp[i+2][j][l]+a;
}
if(dp[i][j][l]>dp[i][j+2][l]+a){ //女买a
dp[i][j][l]=dp[i][j+2][l]+a;
}
if(dp[i][j][l]>dp[i][j][l+1]+c){ //情侣买c
dp[i][j][l]=dp[i][j][l+1]+c;
}
if(dp[i][j][l]>dp[i+1][j+1][l+1]+2*a){ //情侣分开买a
dp[i][j][l]=dp[i+1][j+1][l+1]+2*a;
}
if(dp[i][j][l]>dp[i+2][j+2][l+1]+2*b){ //情侣分开买b
dp[i][j][l]=dp[i+2][j+2][l+1]+2*b;
}
if(dp[i][j][l]>dp[i+3][j][l]+b){ //男买b
dp[i][j][l]=dp[i+3][j][l]+b;
}
if(dp[i][j][l]>dp[i][j+3][l]+b){ //女买b
dp[i][j][l]=dp[i][j+3][l]+b;
}
}
}
}
/*for(int i=n;i>=0;i--)
for(int j=m;j>=0;j--)
for(int l=k;l>=0;l--){
printf("%d %d %d %lld ",i,j,l,dp[i][j][l]);
if(l==0) cout<<endl;
if(j==0) cout<<endl;
} */
cout<<dp[0][0][0]+sum<<endl;
}
}
官方题解出来啦:
#include<stdio.h>
#include<cstring>
Code ( ):
#include<algorithm>
#include<vector>
#include<map>
#include<assert.h>
#include<set>
#include<cmath>
#include<queue>
#include<cstdlib>
#include<iostream>
#include<bitset>
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define rep(i,j,k) for(int i=(int)(j);i<=(int)(k);i++)
#define per(i,j,k) for(int i=(int)(j);i>=(int)(k);i--)
using namespace std;
typedef long long LL;
typedef double db;
const int N=3225;
int n,m,k;LL a,b,c;
LL f[N];
void Main(){
scanf("%d%d%d%lld%lld%lld",&n,&m,&k,&a,&b,&c);
assert(0<=n&&n<=1000);
assert(0<=m&&m<=1000);
assert(0<=k&&k<=1000);
assert(0<=a&&a<=1000000000);
assert(0<=b&&b<=1000000000);
assert(0<=c&&c<=1000000000);
rep(i,0,n+k+m+20)f[i]=(1ll<<60);
f[0]=0;
rep(i,2,n+k+m+20)f[i]=min(f[i],f[i-2]+a);//背包,物品体积为2,费⽤为a
rep(i,3,n+k+m+20)f[i]=min(f[i],f[i-3]+b);//背包,物品体积为3,费⽤为b
per(i,n+k+m+19,0)f[i]=min(f[i],f[i+1]); //考虑不住满的情况
LL ans=1ll<<60;
rep(i,0,k)ans=min(ans,i*1ll*c+f[n+k-i]+f[m+k-i]); //枚举情侣房个数,计算
答案
printf("%lld\n",ans);
}
int main(){
int t;scanf("%d",&t);
assert(1<=t&&t<=50);
while(t--)Main();
return 0;
}