比赛链接:“学佳澳杯”湖北文理学院第一届程序设计竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)
A:国家德比
方法:简单输出问题
代码:
#include<bits/stdc++.h>
//#define int long long//不知道这题为什么加了宏定义会WA,奇奇怪怪。。。
using namespace std;
const int N=2e5+10;
inline void solve(){
int a,b;scanf("%d:%d",&a,&b);
if(a>b) cout<<"Hala Madrid!";
else if(a<b) cout<<"Vamos Barca!";
else cout<<"Draw...";
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
solve();
}
B:吉利数
方法:暴力
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
bool pd(int x){
int ans=0;bool ok=false;
while(x){
if(x%10==6) ok=true;
ans+=x%10;
x/=10;
}
return ok&&ans%6==0;
}
inline void solve(){
int n,m;cin>>n;
int cnt=0;
for(int i=1;i<=n;i++){
if(pd(i)) cnt++,m=i;
}
cout<<cnt<<" "<<m;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
solve();
}
C:咖啡杯
方法:相似比例
#include <bits/stdc++.h>
#define int long long
using namespace std;
double r1,r2,h,t,d,v1,v2,ans;
signed main() {
cin>>r1>>r2>>h>>t>>d;
double r3=r1+(r2-r1)*d/h;
v1=(h-d)*(r2*r2+r3*r3+r2*r3);
v2=d*(r1*r1+r3*r3+r1*r3);
ans=t/v1*v2;
cout<<fixed<<setprecision(10)<<ans;
}
D:数字谜题I
方法:暴力枚举
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int a[N];
int calc(int x){
int ans=1e10;
for(int i=0;i<=31;i++){
for(int j=0;j<=31;j++){
if(i==j) continue;
ans=min(ans,abs(a[i]+a[j]-x));
}
}
return ans;
}
inline void solve(){
a[0]=1;
for(int i=1;i<=31;i++){
a[i]=a[i-1]*2;
}
int n;
while(cin>>n) cout<<calc(n)<<"\n";
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
solve();
}
E:数字谜题II
方法:1:打表
方法:2:二分
代码1:打表
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int Y[N]={0,1,5,14,30,66,147,316,640,1316,2685,5389,10865,21890,43794,87894,176103,352503,705339,1410939,2822283,5644683,11290059,22586380,45177389,90362673,180726709,361467845,722962014,1445926558,2891903234,5783868963,11567775667,23135638583,46271569608,92543451489,185087175589,370174703113,740349599513,1480699709609,2961401728890,5922805611019,11845613688143,23691229216659,47382461525155,94764923639219,189529852873203,379059728863428,758119484738277,1516238988699177,3032478012198573,6064956028042173,12129912122039757,24259824405685918,48519649093187567,97039298227772211,194078596977778807,388157194397204432,776314389397230816,1552628779074933316};
inline void solve(int n){
int ans=1;
for(int i=1;i<=100;i++)
if(n*n>Y[i]) ans=i+1;
else break;
cout<<ans<<"\n";
}
signed main(){
int n;
while(cin>>n) solve(n);
}
代码2:二分
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline void solve(){
int x=0,y=0;
vector<int>vec;
while(x<=1e9){
int i;for(i=x+1;i*i<=y;i++);
x=i;y+=i*i;
vec.push_back(x);
}
int xf;
while(cin>>xf){
//找到第一个大于xf的数的位置
int ans=upper_bound(vec.begin(),vec.end(),xf)-vec.begin();
cout<<ans<<"\n";
}
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
solve();
}
F:区间计数
方法:尺取法
代码:
#include<bits/stdc++.h>
#define int long long
#define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int N=2e5+10;
int n,m;
int a[N],pos[N],f[N];
//pos:代表位置 f:代表i这个人的右边最远不是他的敌人的位置
inline void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];pos[a[i]]=i;
f[i]=n;//初始每一个人的右边最远不是他的敌人的位置是n
}
int j,k;
for(int i=1;i<=m;i++){
cin>>j>>k;
j=pos[j];k=pos[k];
if(j>k) swap(j,k);
f[j]=min(f[j],k-1);
}
j=n;int ans=0;
for(int i=n;i>=1;i--){//累加答案
j=min(j,f[i]);
ans+=j-i+1;
}
cout<<ans;
}
signed main(){
fast;
//int T;cin>>T;
//while(T--)
solve();
}
I:寻宝任务
方法:贪心+BFS+优先队列(堆)
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, x, y, t;
int num[505][505];
bool vis[505][505];
int D[9][2] = {{0, 0}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
struct Node{
int a, b, g;
bool operator<(const Node &tmp) const{//便于大根堆的排序规则
return g < tmp.g;
}
};
void solve(){
cin >> n >> m >> x >> y >> t;
for (int i = 1; i <= n; i++)//初始化地图
for (int j = 1; j <= m; j++)
cin >> num[i][j];
priority_queue<Node> q;
q.push({x, y, t});
int ans = 0;
while (!q.empty()){//BFS
auto [x, y, hp] = q.top();
q.pop();
if (vis[x][y]) continue;//如果访问就continue
vis[x][y] = true;//标记已经访问
if (num[x][y]){//如果当前格子有值,取max//进行下一个点的搜索
ans = max(ans, num[x][y]);continue;
}
for (int i = 1; i <= 8; i++){
//这里的i代表移动方向,同时也代表了移动方向后所要减少的体力值
if (i > hp) break;//如果消耗值>当前体力值,就不用进行移动了
int xx = x + D[i][0], yy = y + D[i][1];
if (xx<1 || yy<1 || xx>n || yy>m) continue;
q.push({xx, yy, hp - i});//更新下一个格子的值
}
}
cout << ans << endl;
}
signed main(){
solve();
}
剩余题后面再补吧。。