长江师范学院第二次校赛

A 观星者

分类考虑四种情况即可

#include<iostream>
using namespace std;

int main(){
    int x1,x2,x3,y1,y2,y3;
    cin>>x1>>y1>>x2>>y2>>x3>>y3;
    int x4,y4;
    if(y1==y2) y4=y3;
    else if(y1==y3) y4=y2;
        else if(y2==y3) y4=y1;
     if(x1==x2) x4=x3;
        else if(x1==x3) x4=x2;
            else if(x2==x3) x4=x1;
    cout<<x4<<' '<<y4<<endl;
	return 0;
}

B 决胜24点

分类讨论多种情况

#include <iostream>
#include <cmath>
using namespace std;
void solve()
{
    double a,b,c;
    cin>>a>>b>>c;
    if (a+b+c==24) 
        cout<<"YES"<<endl;
    else if (a+abs(b-c)==24||c+abs(a-b)==24||b+abs(c-a)==24)
        cout<<"YES"<<endl;
    else if (a*b+c==24||a*c+b==24||b*c+a==24)
        cout<<"YES"<<endl;
    else if (a*b-c==24||a*c-b==24||b*c-a==24)
        cout<<"YES"<<endl;
    else if (a*b*c==24)
        cout<<"YES"<<endl;
    else if (a*b/c==24||a*c/b==24||b*c/a==24)
        cout<<"YES"<<endl;
    else if (a*abs(b-c)==24||c*abs(a-b)==24||b*abs(c-a)==24)
        cout<<"YES"<<endl;
    else if (a*(b+c)==24||c*(a+b)==24||b*(c+a)==24)
        cout<<"YES"<<endl;
    else if ((a+b)/c==24||(a+c)/b==24||(b+c)/a==24)
        cout<<"YES"<<endl;
    else if (a+b/c==24||b+a/c==24||c+a/b==24||a+c/b==24||b+c/a==24||c+b/a==24)
        cout<<"YES"<<endl;
    	else cout<<"NO"<<endl;
}
int main()
{
    int n;
    cin>>n;
    while (n>0)
    {
        solve();
        n--;
    }
    return 0;
}

C 区间质数和

先用前缀和进行区间和查询的优化,再用除2,3以外,素数可以用6n+-1的规律,来对暴力除法试筛选的时间复杂度进行优化至原本的三分之一

#include <iostream>  
#include <cmath>  
using namespace std;    
const int N = 1e6 + 10;   
long long  a[N]={0},s[N]={0};   
long long n, m,l,r;  
bool isPrime(int num) {
  if (num==1) return false;
  if (num==2||num==3) return true;
  if (num%6!=1&&num%6!=5) return false;
  int tmp=sqrt(num);
  for (int i=5;i<=tmp;i+=6)
    if (num%i==0||num%(i+2)==0) return false;
  return true;
}
int main() 
{     
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    long long ans;
    cin>>n>>m;  
   for (long long i=1;i<=n;i++)  
   {
       cin>>a[i]; s[i]=s[i-1]+a[i];
       if(!isPrime(a[i])) s[i]-=a[i];
   }  
    while(m--){
       cin>>l>>r; 
       ans=s[r]-s[l-1];
       cout<<ans<<endl;
    }
   return 0;  
}

D 迷宫之主

要求不同位置进入迷宫的最长路径,可以想到用bfs走出所有的最短路径,取最大值

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
int h,w,res=-1e18;
char mp[25][25];
int ds[25][25];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
void bfs(int a,int b){
    memset(ds,-1,sizeof ds);
    queue<PII> q;q.push({a,b});
    ds[a][b]=0;
    while(!q.empty()){
        PII start=q.front();q.pop();
        for(int i=0;i<4;i++){
            int x=dx[i]+start.first;int y=dy[i]+start.second;
            if(mp[x][y]=='.'&&ds[x][y]==-1){
                ds[x][y]=ds[start.first][start.second]+1;
                q.push({x,y});
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    cin>>h>>w;
    for(int i=1;i<=h;i++)for(int j=1;j<=w;j++) cin>>mp[i][j];
    
    for(int i=1;i<=h;i++)for(int j=1;j<=w;j++)
        if(mp[i][j]=='.') {
            bfs(i,j);
            for(int k=1;k<=h;k++)for(int l=1;l<=w;l++)
                res=max(res,ds[k][l]);
        }
    cout<<res<<'\n';
    return 0;
}

E 小A在摸鱼!!!

分类讨论,对于第二种有比较巧妙的交换a,b,这样可以少写一次判断

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
    long long int a,b,count=0;
    scanf("%lld%lld",&a,&b);
    while(a!=b)
    {
        if (a<b) 
        {
            b=b-a;
            count++;
        }
        swap(a,b);
    }
    printf("%lld",count);
    return 0;
}

F 派蒙的数组

贪心,要使得代价最小,因为正负数都有,所以要让正数足够下,那就让正数的下标取到1,负数直接×当前下标即可

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const ll N = 1e6+10;
ll a[N]={0};
int main()
{
    ll n;
    ll sum=0;
    cin >> n;
    for (ll i = 1;i <= n;i ++)
    {
        cin >> a[i];
        if(a[i]>0)
            sum+=a[i];
        else
            sum+=a[i]*i;
    }
    cout << sum;
    return 0;
}

G 摸鱼时间到

是一道大模拟题,综合比较强,有前缀和,数学和二分查找

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int a[N];  // 存储每个任务的到达时间
vector<int> rest(N);  // 存储相邻两个任务之间的时间间隔
vector<ll> sum(N);  // 前缀和数组,表示前 i 个时间间隔的总和

int main(){
    int n,q;
    cin>>n>>q;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=1;i<n;i++) rest[i]=a[i]-a[i-1];  // 计算相邻两个任务之间的时间间隔
    sort(rest.begin()+1,rest.begin()+n);  // 将时间间隔从小到大排序,为二分查找
    for(int i=1;i<n;i++) sum[i]=sum[i-1]+rest[i];  // 计算时间间隔的前缀和数组
    while(q--){
        int k,p;
        cin>>k>>p;
        int index=upper_bound(rest.begin()+1,rest.begin()+n,k)-rest.begin();  // 二分查找最后一个时间间隔小于等于 k 的位置
        ll tmp=sum[n-1]-sum[index-1]-k*((n-1)-(index-1));  // 计算在该位置之后的任务间隔总和
        printf("%s\n",(tmp>=p)?"YES":"NO"); 
    }

    return 0;
}

H 简单计数题

三元组,要求下标不相同,元素也不同,三个元素相加为一个目标值,很容易想到暴力,但是会超时,并且不好判重,可以用双指针来做

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,t;cin>>n>>t;
    vector<int>a(n);
    for(int i=0;i<n;i++) cin>>a[i];
    sort(a.begin(),a.end());
    int res=0;
    for(int i=0;i<n-2;i++)
    {
    if(i>0&&a[i]==a[i-1]) continue;
    int left=i+1,right=n-1;
        while(left<right)
        {
	       int sum=a[i]+a[left]+a[right];
	       if(sum==t)
           {
	           res++;
	           while(left<right&&a[left]==a[left+1]) left++;
	           while(left<right&&a[right]==a[right-1]) right--;
	           left++;
	           right--;
            }
	       else if(sum<t) left++;
		      else right--;
        }
    }
	cout<<res<<'\n';
    return 0;
}

I 小A玩篱笆

思维题,要围成一个矩形,首先要考虑是一个偶数,然后再观察是不是四的倍数,如果是四的倍数就会少一种,因为是两两配对,如果出现正方形,那两两配对了两个实际上是一个,所以要减一种

#include <iostream>
using namespace std;
int main()
{
    long long int n;
    cin>>n;
    if (n%2) cout<<"0";
    else if (n%4==0)
        cout<<n/4-1;
    else cout<<n/4;
    return 0;
}

J-火星之旅

考点:大模拟

#include<bits/stdc++.h>

using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

const int N = 1e5 + 10;
typedef long long ll;

struct node {
    ll v, w; // 终点, 权重
};

struct Graph {
    int numv; // 图点的数量
    vector<vector<node>> adlist; // 邻接表
    vector<ll > dis; // 某个点到某个点的距离
    vector<bool > vis; // 标记访问
    // 构造函数
    Graph(int n) : numv(n), adlist(n + 1), dis(n + 1, 1e14), vis(n + 1, false) {

    }
    // 向邻接表中添加边和权值
    void add(int a, int b, int c) {
        adlist[a].push_back({b, c});
    }
    // 堆优化版dijk
    void dijkstra(int s) {
        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int >>> q;
        dis[s] = 0;
        q.push({0, s});
        while(q.size()) {
            auto it = q.top();
            q.pop();
            ll u = it.second, d = it.first;
            if(vis[u]) {
                continue;
            }
            vis[u] = true;
            for(auto &[v, w] : adlist[u]) {
                if(dis[v] > d + w) {
                    dis[v] = d + w;
                    q.push({dis[v], v});
                }
            }
        }
    }
};

struct SegmentTree {
    vector<ll > tree;
    vector<int > nums;
    int numVertices;
    SegmentTree(int n) : numVertices(n), tree((n + 1) << 2, 0), nums(n) {}

    void push_up(int p) {
        tree[p] = min(tree[p << 1], tree[p << 1 | 1]);
    }

    void add(int i, int x) {
        nums[i] = x;
    }

    void build(int p, int pl, int pr, vector<ll > &dis1, vector<ll > &dis2) {
        if (pl == pr) {
            tree[p] = dis1[pl] + (dis2[pl] + nums[pl] - 1) / nums[pl];
            return;
        }
        else {
            int mid = pl + pr >> 1;
            build(p << 1, pl, mid, dis1, dis2);
            build(p << 1 | 1, mid + 1, pr, dis1, dis2);
            push_up(p);
        }
    }

    void change(int p, int pl, int pr, int k, vector<ll > &dis1, vector<ll > &dis2) {
        if (pl == pr) {
            tree[p] = dis1[pl] + (dis2[pl] + nums[pl] - 1) / nums[pl];
            return ;
        }
        else {
            int mid = pl + pr >> 1;
            if (k <= mid)    change(p << 1, pl, mid, k, dis1, dis2);
            else    change(p << 1 | 1, mid + 1, pr, k, dis1, dis2);
            push_up(p);
        }
    }

    ll query(int p, int pl, int pr, int l, int r) {
        if (l <= pl && pr <= r)  return tree[p];
        int mid = pl + pr >> 1;
        ll v = 0;
        if (l <= mid) v = fmin(v, query(p << 1, pl, mid, l, r)) ;
        if (r > mid) v = fmin(v, query(p << 1 | 1, mid + 1, pr, l, r)) ;
        return v;
    }
};

int main() {
    IOS;
    int n, m, k;
    cin >> n >> m >> k;
    Graph g(n), neg(n); // 正图和反图, 反图用于计算星际旅游最小价值
    for(int i = 1; i <= m; i++) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        g.add(a, b, c), neg.add(b, a, d);
    }

    // 计算出到每个城市需要的货币数量
    g.dijkstra(1), neg.dijkstra(n);
    SegmentTree sg(N);
    
    for(int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        sg.add(i, x);
    }
    sg.build(1, 1, n, g.dis, neg.dis);
    for(int i = 1; i <= k; i++) {
        int k, x;
        cin >> k >> x;
        sg.add(k, x);
        sg.change(1, 1, n, k, g.dis, neg.dis);
        cout << sg.query(1, 1, n, 1, n) << "\n";
    }
    return 0;
}

K-玩游戏

考点:大模拟

#include <bits/stdc++.h>
#define endl "\n"

using namespace std;

constexpr int INF = 0x3f3f3f3f;
constexpr int N = 1e5 + 10;

int n, m, k;
typedef struct T{
    int h, a, b, c, d, e, w, g;
}T;
queue<T>A, B;
//小A操作
void move(queue<T> &A, queue<T> &B)
{
    T t1 = A.front();
    A.pop();
    T* t2 = &B.front();
	int ww = max(t1.a - t2->c, 0);
	int mm = max(t1.b - t2->d, 0);
	int z = 0;
	if (t1.g >= t1.e) z = t1.w;
    
	if (ww >= z && ww >= mm)//物理攻击
	{
		++ t1.g;
		t2->h = max(0, t2->h - ww);
	}else if (mm >= z && mm >= ww)//魔法攻击
	{
		++ t1.g;
		t2->h = max(0, t2->h - mm);
	}else if (z >= 0) // 终极技能
    {
		t2->h = max(0, t2->h - z);
		t1.g -= t1.e;
	}
    A.push(t1);
	if (t2->h == 0) B.pop();
}

void solve()
{
    if (A.empty() && B.empty())
    {
        cout << "Draw" << endl;
        return ;
    }
	for (int i = 0; i < k; ++ i)//回合
	{
		move(A, B);
 		if (B.empty())//判断B宝可梦数量
		{
			cout << "Alice" << endl;
//          cout << k << endl;//结束在第几回合
            return ;
		}       
		move(B, A);
        if (A.empty())//判断A宝可梦数量
		{
			cout << "Bob" << endl;
//          cout << k << endl;//结束在第几回合
			return ;
		}
	}
	cout << "Draw" << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	cin >> n >> m >> k;
	for (int i = 0; i < n; ++ i)
    {
        T t;
        cin >> t.h >> t.a >> t.b >> t.c >> t.d >> t.e >> t.w;
        t.g = 0;
        A.push(t);
    }

	for (int i = 0; i < m; ++ i)
    {
        T t;
        cin >> t.h >> t.a >> t.b >> t.c >> t.d >> t.e >> t.w;
        t.g = 0;
        B.push(t);
    }
	solve();
	return 0;
}
全部评论

相关推荐

今天 20:45
天津大学 C++
求问美团还有转正没开奖的吗
投递美团等公司10个岗位 >
点赞 评论 收藏
分享
北冥有鱼吗:工作忙,现在没工作了哈哈哈
点赞 评论 收藏
分享
3 收藏 评论
分享
牛客网
牛客企业服务