牛客IOI周赛22-普及组

1.战争尾声
题目链接
在这里插入图片描述
题解:
因为数据量非常小,直接遍历每一个点即可

代码:

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;

typedef pair<int, int> pii;

double getlength(double x, double y, pii v)
{
    
    

  return sqrt((x - v.first) * (x - v.first) + (y - v.second) * (y - v.second));
}

int main()
{
    
    

  vector<pii> v;

  int n;
  cin >> n;
  pii a;
  for (int i = 1; i <= n; i++)
  {
    
    
    cin >> a.first >> a.second;
    v.push_back(a);
  }

  for (int i = 1; i <= 200; i++)
    for (int j = 1; j <= 200; j++)
    {
    
    
      double x = i;
      double y = j;
      double length;
      length = getlength(x, y, v[0]);
      int uu=(int)v.size();
      for (int o = 0; o < uu; o++)
      {
    
    
        if (length - getlength(x, y, v[o]) > 0.0001||length - getlength(x, y, v[o]) <- 0.0001)
          break;
        
        if (o == uu - 1)
        {
    
    
          cout << x << " " << y;
          system("pause");
          return 0;
        }
      }
    }

  cout << "War is cruel." << endl;
  system("pause");
}

2.签订协议
题目链接
在这里插入图片描述

题解:
我们建立一个包含国家战力和编号的结构体,按国家战力进行由大到小的排序,依次遍历,如何后一个的编号比前一个小,说明进行了一次轮转

代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N=1e6;
struct member
{
    
    
  int val;
  int id;

  bool operator <(const member &a)const
  {
    
    
    return val>a.val;
  }


}a[N];

int n;

int main()
{
    
    

    cin>>n;
    for(int i=1;i<=n;i++ )
    {
    
    
      cin>>a[i].val;
      a[i].id=i;
    }

    sort(a+1,a+n+1);
    int ans=1;
    for(int i=2;i<=n;i++)
      if(a[i].id<a[i-1].id)
          ans++;

          cout<<ans;
}


3.照看小猫

题目链接
在这里插入图片描述
题解:
我们按字数要求从小到大对猫进行排序,并且优先考虑字数长度小的,因为先考虑字数小的一定会对字数大的猫选名字产生影响,但字数大的猫选名字不一定会对字数小的猫产生影响。具体见代码注释

代码:

#include <iostream>
#include <cstring>
#include <math.h>
#include <algorithm>

using namespace std;
typedef long long l;
const int mod = 77797;

int a[10000+10];
int n;
l b[15];

int main()
{
    
    

  cin >> n;

  for (int i = 1; i <= n; i++)
    scanf("%d", a + i);

  sort(a + 1, a + n + 1);//从小到大排序

  b[1] = 26;
  for (int i = 2; i <= 11; i++)//计算对应字数所有的情况数
  {
    
    
    b[i] = b[i - 1] * 26;//计算名字为i个字母时的情况数
    b[i - 1] += b[i - 2];//计算名字的字母小于等于i-1时情况的数
  }

  l ans = 1;

  for (int i = 1; i <= n; i++)
  {
    
    
    l g = b[a[i]] - i + 1; //前面有i-1个人已经选好了名字,不能重复
    if (g < 1)//没有能选的名字了
        
    {
    
    
      cout << "-1" << endl;
      return 0;
    }
    g %= mod;
    ans = ans * g % mod;//事件与事件间是乘法关系
  }

  cout << ans << endl;
}


4.路线规划
题目链接
在这里插入图片描述
题解:
最初读题目以为是状压dp,但看见走过的路最少的前提下,可见就是一个最小生成树的模板题
代码:

#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n, m, x, y, num, ans, fa[200021];
struct node
{
    
    
	int x, y;
	ll l;
}a[2000021];
bool cmp(node a, node b)
{
    
    
	return a.l < b.l;
}
ll find(ll x)
{
    
    
	if (fa[x] == x) return x;
	return fa[x] = find(fa[x]); 
}
int main()
{
    
    
	scanf("%lld%lld", &n, &m);
	for (ll i = 1; i <= m; ++i)
		scanf("%lld%lld%lld", &a[i].x, &a[i].y, &a[i].l);
	sort(a + 1, a + 1 + m, cmp);
	for (ll i = 1; i <= n; ++i)
		fa[i] = i;
	num = 1;
	for (ll i = 1; i <= m; ++i)
	{
    
    
		x = find(a[i].x);
		y = find(a[i].y);
		if (x != y)
		{
    
    
			num++;
			ans += a[i].l;
			fa[x] = y;
			if (num == n) break;
		}
	}
	printf("%lld", ans * 2);
	return 0;
}

在这里插入图片描述
                                                                                                       —从零开始的异世界生活

猜你喜欢

转载自blog.csdn.net/jahup/article/details/113401336