今天呢还是日常写各种打假算法~
但不得不说他们学校出的题质量还是很好的
B 运筹帷幄: dfs(细节~)考虑到数据范围很小,当然是神搜了~,其实6层for也是不错的选择,有几个细节很坑就是:只要被冰了就一直冰着,英雄攻击只能用一次!(弱弱就死在这里~),法术伤害叠加,英雄伤害不叠加。然后记录状态:(当前剩余技能点val ,伤害总和num,法伤加成now,数组x,是否冰冻flag),然后d就行了 |
链接:https://ac.nowcoder.com/acm/contest/11290/B
来源:牛客网
#pragma GCC optimize(2) #include <bits/stdc++.h> #define debug(x) cout<<#x<<":"<<x<<endl; typedef long long ll; using namespace std; #define rep(i,j,n) for(ll i=j;i<=n;i++) #define per(i,j,n) for(ll i=j;i>=n;i--) #define pr(x) printf("%lld\n",x) typedef unsigned long long ull; typedef unsigned int us; const ll INF=1e18+7;const double eps=1e-8,pi=acos(-1); const ll mod=1000000007; const ll maxx=1e5+700; inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;} ll n,m,h; ll maxl=0; map<string,ll>mp; string a[10]={ "1","Frostbolt","IceLance","Fireball","BloodmageThalnos","CosmicAnomaly","Alexstrasza"}; ll cishu[20]; void dfs(ll val,ll num,ll now,ll x[],ll flag) // 剩余 当前值 伤害, 数组 ,冰冻 { if(val<0) return ; rep(i,1,5) { if(x[i]>cishu[i]) return ; } if(val>=0) { // printf("%lld\n",num); maxl=max(maxl,num); } ll y[8]; rep(j,1,5) y[j]=x[j]; y[1]++; dfs(val-2,num+3+now,now,y,1); y[1]--; y[2]++; if(flag==0) dfs(val-1,num,now,y,1); else dfs(val-1,num+4+now,now,y,1); y[2]--; y[3]++; dfs(val-4,num+6+now,now,y,flag); y[3]--; y[4]++; dfs(val-2,num,now+1,y,flag); y[4]--; y[5]++; dfs(val-4,num,now+2,y,flag); y[5]--; dfs(val-2,num+1,now,y,flag); } int main() { ll t; cin>>n>>m>>h; string b; rep(i,1,n) { cin>>b; mp[b]++; } rep(i,1,5) cishu[i]=mp[a[i]]; ll x[8]={0}; dfs(m,0,0,x,0); //pr(maxl); if(maxl>=h) printf("Win\n"); else { printf("Lose\n"); pr(maxl); } return 0; }
题目描述
Korialstrasz和Neltharion正在打牌。现在局势对Korialstrasz非常不利,他已经不能活到下一个回合了,所以他想知道在这个回合内能否击败对手。
Korialstrasz的卡组是冰法,现在他拥有 n 张手牌,每张手牌均为以下 6 种卡牌中的一种:
1. Frostbolt,消耗 2 点法力水晶,对一个角色造成 3 点伤害,并使其冻结
2. IceLance,消耗 1 点法力水晶,冻结一个角色,如果该角色已被冻结,则改为对其造成 4 点伤害
3. Fireball,消耗 4 点法力水晶,对一个角色造成 6 点伤害
4. BloodmageThalnos,消耗 2 点法力水晶,你的法术伤害加 1
5. CosmicAnomaly,消耗 4 点法力水晶,你的法术伤害加 2
6. Alexstrasza,消耗 9 点法力水晶,将一名玩家的生命值变为 15(使用这张牌造成的生命值改变不视为伤害)
以上卡牌中BloodmageThalnos和Alexstrasza为传说卡,至多各有一张,其余卡牌至多各有两张。在回合开始时Korialstrasz拥有 m 点法力水晶,使用卡牌会消耗相应的法力水晶,如果剩余的法力水晶数量小于卡牌消耗的法力水晶数量,则无法使用该卡牌。
除了使用手牌打出伤害,Korialstrasz还可以使用英雄技能,英雄技能每回合只能使用一次,会消耗 2 点法力水晶对一个角色造成 1 点伤害。
Neltharion的英雄拥有 h 点生命值,也就是说Korialstrasz本回合内只要造成至少 h 点伤害即可获胜。回合开始时 Neltharion 的英雄并没有被冻结。
输入描述:
第一行输入为 n,m,h,分别表示手牌数量,法力水晶数量与对手生命值。
之后 n 行每行输入一张卡牌的名称。
保证 0≤n≤100\le n \le 100≤n≤10,1≤m≤101\le m \le 101≤m≤10,1≤h≤301\le h \le 301≤h≤30。
输出描述:
如果Korialstrasz能够获胜,仅输出Win,否则输出两行,第一行输出Lose,第二行输出能够打出的最高伤害。示例1
输入
复制10 10 20 IceLance Fireball Frostbolt CosmicAnomaly Fireball BloodmageThalnos IceLance Frostbolt Alexstrasza CosmicAnomaly
10 10 20 IceLance Fireball Frostbolt CosmicAnomaly Fireball BloodmageThalnos IceLance Frostbolt Alexstrasza CosmicAnomaly输出
复制Win
Win说明
可以先打出一张CosmicAnomaly,然后依次打出两张Frostbolt与两张IceLance,造成5+5+6+6=22点伤害,消耗10点法力水晶。示例2
输入
复制2 4 6 IceLance IceLance
2 4 6 IceLance IceLance输出
复制Lose 5
Lose 5说明
伤害最高的打法是使用两张IceLance与一次英雄技能,造成0+4+1=5点伤害,消耗4点法力水晶,不足以击败对手。示例3
输入
复制3 3 10 IceLance Frostbolt IceLance
3 3 10 IceLance Frostbolt IceLance输出
复制Lose 7
Lose 7说明
由于只有3点法力水晶,最多只能使用一张Frostbolt一张IceLance,造成7点伤害。备注:
关于法术伤害的理解:在本题中,通过手牌造成的伤害均为法术伤害,享受法术伤害加成,而英雄技能造成的伤害不是法术伤害。法术伤害加成可以叠加,也不会随着法术的使用而衰减或消失。
|
#include<bits/stdc++.h>
using namespace std;
map<int,int> s;
int main(){
int n,x;
int maxx=0,y=-1;
cin>>n;
for(int i=0;i<n;++i){
cin>>x;
s[x]++;
if(s[x]>maxx){
maxx=s[x];
y=x;
}
}
if(maxx==n) cout<<"-1";
else cout<<y;
return 0;
}
然后我自己写了个二分加set维护所有的情况~(想了好久呢~),首先长度是有序递增的可以二分,二分用一个set<ll>st[100007] 处理所有出现的次数的数。nice~ 说实话我当时还傻傻的好奇别人的二分是咋判断的呢~
//#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
#define pr(x) printf("%lld\n",x)
typedef unsigned long long ull;
typedef unsigned int us;
const ll INF=1e18+7;const double eps=1e-8,pi=acos(-1);
const ll mod=1000000007;
const ll maxx=1e6+700;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m;
ll a[maxx];
ll p;
ll vis[100007];
set<ll>st[100007];
ll judge(ll x)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
st[i].clear();
ll maxl=0;
ll num;
rep(i,1,x)
{
vis[a[i]]++;
num=vis[a[i]];
st[num].insert(a[i]);
maxl=max(maxl,num);
st[num-1].erase(a[i]);
}
if(st[maxl].size()>=2)
{
p=*st[maxl].begin();
return 1;
}
rep(i,x+1,n)
{
vis[a[i-x]]--;
num=vis[a[i-x]];
st[num].insert(a[i-x]);
st[num+1].erase(a[i-x]);
if(num+1==maxl && st[num+1].empty())
maxl--;
vis[a[i]]++;
num=vis[a[i]];
st[num].insert(a[i]);
maxl=max(maxl,num);
st[num-1].erase(a[i]);
if(st[maxl].size()>=2)
{
p=*st[maxl].begin();
return 1;
}
}
return 0;
}
int main()
{
ll t;
cin>>n;
rep(i,1,n) read(a[i]);
int flag=0;
rep(i,2,n)
{
if(a[i]!=a[1]) flag=1;
}
if(flag==0) {
printf("-1\n");
return 0;
}
ll l=1,r=n;
ll ans=0;
ll len=0;
while(l<=r)
{
ll mid=(l+r)>>1;
if(judge(mid))
{
if(mid>len)
{
ans=p;
len=mid;
}
l=mid+1;
}
else r=mid-1;
}
printf("%lld\n",ans);
return 0;
}
F 反复读密码锁 (其实就是个小规律,如果n的二进制的长度和二进制0的个数同奇偶,则0,否则为1) |
//#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
#define pr(x) printf("%lld\n",x)
typedef unsigned long long ull;
typedef unsigned int us;
const ll INF=1e18+7;const double eps=1e-8,pi=acos(-1);
const ll mod=1000000007;
const ll maxx=1e6+700;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m;
ll a[maxx];
int main()
{
ll t;
cin>>t;
while(t--)
{
read(n);
ll len=0;
ll num=0;
while(n)
{
if(n%2==0) num++;
len++;
n/=2;
}
if(len%2!=num%2) printf("1\n");
else printf("0\n");
}
return 0;
}
H松果痰抖闪电鞭 每五个一循环,打个表就找到规律了
//#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
#define pr(x) printf("%lld\n",x)
typedef unsigned long long ull;
typedef unsigned int us;
const ll INF=1e18+7;const double eps=1e-8,pi=acos(-1);
const ll mod=1000000007;
const ll maxx=1e6+700;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m;
double num[maxx];
int main()
{
ll t;
double a,b;
ll k;
cin>>a>>b>>k;
num[1]=a;
num[2]=b;
rep(i,3,8)
{
num[i]=(1.0+num[i-1])/num[i-2];
}
//printf("%.5f\n%.5f\n",a,b);
ll p=k%5;
if(p==0) p=5;
printf("%.10lf\n",num[p]);
return 0;
}
J ACM基地招新大会
找左边第一个比他大的会用栈,两个就不会了呢咋,自己写了个假算法T%95,依然是考虑栈,但要记录的是左侧第一个比他大的位置,找到之后利用前面已经有的位置继续往前跑就行,大题复杂度8*n左右吧。
#include <iostream>
#include <stack>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 100005;
int a[maxn], n, m = -1, L[maxn], ans[maxn];
stack<int> s;
int main() {
scanf("%d", &n);
s.push(0);
a[0] = inf;
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
while(a[s.top()] <= a[i]) s.pop();
L[i] = s.top();
if(L[i] == 0) {
printf("1\n");
ans[i] = 1;
} else {
int k = (a[i] >= a[i - 1] && L[i] == L[i - 1]) ? ans[i - 1] - 1 : L[i] - 1;
while(a[k] <= a[i]) k--;
printf("%d\n", k + 1);
ans[i] = k + 1;
}
s.push(i);
}
return 0;
}
J不讲武德: 方法太多了,随便搞都行。