题目链接
A-红石音乐
我打比赛怎么还学会了音乐知识题意:大概就是有音符A1 B1 C1 D1 到 A7 B7 其中A1#代表升半调,A1b 代表降半调。B 到C E到F 只有半调
给你一个调,要求从5个基本调每次往上调半调 调到当前的调 的最小次数是多少
做法:预处理所有调所在第几层就可以了。需要注意 的是数据范围含有b 这种降半调的 就很坑。
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline ll read()
{
ll x=0,w=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
return w==1?x:-x;
}
map<string,int>mp;
int main()
{
int id=0;
for(int i=1;i<=8;++i){
char num=i+'0';
for(int j=0;j<7;++j){
char ch=j+65;
string s;
s+=ch;
s+=num;
s+="b";
mp[s]=id;
s="";
s+=ch;
s+=num;
mp[s]=++id;
//cout<<s<<endl;
if(j==1||j==4) continue;
s="";
s+=ch;
s+=num;
s+="#";
mp[s]=++id;
//cout<<s<<endl;
}
//s+="F";s+=c;s+="#";
}
int n=read();
int res=0;
rep(i,1,n)
{
string s;
cin>>s;
int ans=100000;
if(mp[s]>=mp["F1#"]) ans=min(ans,mp[s]-mp["F1#"]);
if(mp[s]>=mp["F2#"]) ans=min(ans,mp[s]-mp["F2#"]);
if(mp[s]>=mp["F3#"]) ans=min(ans,mp[s]-mp["F3#"]);
if(mp[s]>=mp["F4#"]) ans=min(ans,mp[s]-mp["F4#"]);
if(mp[s]>=mp["F5#"]) ans=min(ans,mp[s]-mp["F5#"]);
res+=ans;
}
printf("%d\n",res);
}
D-斐波那契数列?
做法:这题一眼,嗯 矩阵快速幂没跑了,找模数的时候发现没有,居然是求浮点型的,这题有一招巧招:暴力加,加到后面这个除法就特别小了,就没必要继续求了。
#include<bits/stdc++.h>
using namespace std;
double a[505];
int main()
{
int n;cin>>n;
a[1]=0.5;
a[2]=0.25;
double ans=0;
for(int i=1;i<=n;i++)
{
if(i>2)a[i]=a[i-1]*0.5+a[i-2]*0.25;
if(a[i]<1e-11)break;
ans+=a[i];
}
printf("%.9lf",ans);
return 0;
}
E-樱桃蛋糕
做法:由于x 、y大于0,所以向上和向右走无需考虑,向下和向左的保存。
刚开始的时候,考虑向下走:最短走到y=0的位置,所以当前这个点的最长时间是y,
如果y>=x 则代表可以相遇,那么相遇一定是中间的位置,原路返回到家,总时间消耗就是x+y
模拟一下就可以了。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10,mod=1e9+7;
int n,m;
struct node{
int x,y,d;
bool operator<(const node &z)const{
return x+y<z.x+z.y;
}
}a[N];
int main()
{
cin>>n;
for(int i=1,x,y,d;i<=n;i++){
scanf("%d%d%d",&x,&y,&d);
if(d==1||d==3)continue;
if(d==2)a[++m]={x,y,d};
else a[++m]={x,y,d};
}
sort(a+1,a+1+m);
int now=0,ans=0;
for(int i=1;i<=m;i++){
if(a[i].d==2){
if(a[i].y-now>=a[i].x){
ans++;now=a[i].x+a[i].y;
}
}
else{
if(a[i].x-now>=a[i].y){
ans++;
now=a[i].x+a[i].y;
}
}
}
printf("%d\n",ans);
return 0;
}
F-爱买手办的张三
简单题
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline ll read()
{
ll x=0,w=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
return w==1?x:-x;
}
const int N=32;
int f[N],X[N],len;
vector<int>ans;
int mx;
void dfs(int id,int val)
{
if(ans.size()>mx) return ;
if(id>len){
ans.push_back(val);
return ;
}
dfs(id+1,val+X[id]);
dfs(id+1,val);
}
int main()
{
f[0]=1;
rep(i,1,30) f[i]=f[i-1]*2;
mx=1000000;
int x=read();
for(int i=0;i<=30;++i){
if(x&(1<<i)) X[++len]=f[i];
}
dfs(1,0);
printf("1\n%d\n",x);
sort(ans.begin(),ans.end());
printf("%d\n",ans.size());
for(int v:ans) printf("%d\n",v);
}
J-红绿灯
做法:补题,看官方题解
大佬的题解:
大概就是构造合法的 绿黄红 的颜色顺序,且不能有交叉或者顺序不对 两种情况。
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 1e6 + 5;
map<pair<int,string>, bool> v;
int cnt[N];
ll n,T;
int check(){
string t;
for(int i=0;i<T;i++){
if(t=="Yellow" && v.count(mp(i,"Green"))) return 1;//黄绿
if(t=="Red" && v.count(mp(i,"Yellow"))) return 1;//红黄
//if(t=="Green" && v.count(mp(i,"Red"))) return 1;//绿红 ??56行的代码保证了没有这种情况
if(t=="Red" && v.count(mp(i,"Green"))) return 1;//红绿
if(cnt[i]>1) return 1;
if(v.count(mp(i,"Green"))) t="Green";
if(v.count(mp(i,"Yellow"))) t="Yellow";
if(v.count(mp(i,"Red"))) t="Red";
}
return 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>T;
int m1=0,m2=INF;
int flag=0;
for(int i=1;i<=n;i++){
int x;string s;
cin>>x>>s;
if(flag) continue;
x=x%T;
if(s=="Yellow" && x<=0) {cout<<i<<'\n';flag=1;}//黄前面没有绿了
if(flag) continue;
if(s=="Red" && x<=1) {cout<<i<<'\n';flag=1;}//红前面不够绿黄放下
if(flag) continue;
if(s=="Green" && x>=T-2) {cout<<i<<'\n';flag=1;}//绿后面没有黄红的位置
if(flag) continue;
if(s=="Yellow" && x>=T-1) {cout<<i<<'\n';flag=1;}//黄后面没有红的位置
if(flag) continue;
if(s=="Green") m1=max(m1,x);//分界线m1,m2
if(s=="Red") m2=min(m2,x);
if(m1+1>=m2) {cout<<i<<'\n';flag=1;}
if(flag) continue;
if(!v.count(mp(x,s))) v[mp(x,s)]=true,cnt[x]++;
if(check()) {cout<<"check"<<i<<'\n';flag=1;}
}
if(flag) return 0;
cout<<"Correct!\n";
return 0;
}
/*
3 4
0 Green
1 Green
2 Red
*/
M-送礼物
做法:线段树维护最长上升子序列,经典题了。
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline ll read()
{
ll x=0,w=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
return w==1?x:-x;
}
const int N=2e5+10;
ll a[N],ans,X[N],len;;
int n,fa[N];
/*线段树部分*/
struct tree
{
int num,id;
}mx[4*N];
tree Max(tree a,tree b)
{
if(a.num>b.num) return a;
else if(a.num<b.num) return b;
else if(a.id>b.id) return a;
return b;
}
tree qu(int id,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return mx[id];
tree ans={0,0};
int mid=l+r>>1;
if(ql<=mid) ans=qu(id<<1,l,mid,ql,qr);
if(qr>mid) ans=Max(ans,qu(id<<1|1,mid+1,r,ql,qr));
return ans;
}
int get(ll x)
{
return lower_bound(X+1,X+1+len,x)-X;
}
void up(int id,int l,int r,int pos,int num,int tid)
{
if(l==r){
if(num>=mx[id].num){mx[id].num=num;mx[id].id=tid;}
return;
}
int mid=l+r>>1;
if(pos<=mid) up(id<<1,l,mid,pos,num,tid);
else up(id<<1|1,mid+1,r,pos,num,tid);
mx[id]=Max(mx[id<<1],mx[id<<1|1]);
}
int main()
{
n=read(),ans=read();
rep(i,1,n){a[i]=read();X[++len]=a[i];fa[i]=i;}
sort(X+1,X+1+len);
len=unique(X+1,X+1+len)-X-1;
int now=0,mxx=0;
rep(i,1,n)
{
int pos=get(a[i]);
tree t={0,0};
if(pos-1>=1) {
t=qu(1,1,len,1,pos-1);
if(t.id!=0) fa[i]=t.id;
//printf("i:%d tid:%d\n",i,t.id);
}
if(t.num+1>=mxx){mxx=t.num+1;now=i;}
up(1,1,len,pos,t.num+1,i);
}
stack<int>sta;
while(now!=fa[now]){
ans+=a[now];sta.push(now);now=fa[now];
}
ans+=a[now];
sta.push(now);
printf("%lld\n%d\n",ans,sta.size());
while(sta.size()) printf("%d\n",sta.top()),sta.pop();
}
/*
10 0
-1 -2 -3 -4 5 6 7 8 -10 9
*/