后话,
一个 2 6 10 26^{10} 2610会爆longlong吗??????????
我真的qwqwqw…qwq(赛中走上了高精度,一直wa到哭qwq)
A战争尾声
题意:
有n个点(x,y)且范围都是 ( 1 , 200 ) (1,200) (1,200),现在要你找到一个点,使得它到所有其他点的距离最小。
n的范围也只有200。
输出:
最小的点
思路:
由于n小,直接暴力枚举答案即可。(根据横纵坐标即可)
AC
# include <bits/stdc++.h>
# define fi first
# define se second
# define mp make_pair
using namespace std;
const int N = 220;
const double eps = 1e-4;
typedef pair<int,int>pa;
int n;
pa point[N];
double getdis(int i, pa x){
return sqrt( (point[i].fi-x.fi)*(point[i].fi-x.fi) + (point[i].se-x.se)*(point[i].se-x.se) );
}
void init(){
cin>>n;
for(int i = 1; i <= n; i ++ )cin>>point[i].fi>>point[i].se;
}
const string no="War is cruel.";
bool check(pa p){
double dis = getdis(1,p);
for(int i = 2; i <= n; i ++ ){
if(fabs(dis-getdis(i,p))>eps)return false;
}
return true;
}
void sol(){
bool ok = false;
for(int x = 1;x <=200&&!ok; x++ ){
for(int y = 1;y <= 200&&!ok; y ++ ){
pa p = {
x,y};
if(!check(p))continue;
ok = true;
cout<<x<<' '<<y<<endl;
// break;
}
}
if(!ok)cout<<no<<endl;
}
int main(){
ios::sync_with_stdio(0);
//int n;
init();
sol();
return 0;
}
B 签订协议
题意:
思路1(优先队列nlogn)
可以考虑用一个优先队列,去维护,战力最高的在队首。
之后每次出队,就行了。假如当前top的位置 在pre的前面,那么ans++。
AC1
# include <bits/stdc++.h>
# define fi first
# define se second
# define mp make_pair
# define pb push_back
using namespace std;
typedef pair<int,int>pa;
priority_queue<pa> q;
int main(){
ios::sync_with_stdio(0);
int n;
cin>>n;
int x;
for(int i = 1; i <= n; i ++ ){
cin>>x;
q.push(mp(x,i));
}
int pre = n+1, ans = 0;
while(!q.empty()){
int idx = q.top().se;
q.pop();
if(idx<pre)ans++;
pre = idx;
}
cout<<ans<<endl;
return 0;
}
思路2(离散化nlogn)
先把数组离散化,之后暴力枚举,每个战力最小的元素(这一步可以On查询)。
其实代码,和上面差不多,只不过是,先预处理出了战力的顺序。
AC2
# include <bits/stdc++.h>
using namespace std;
const int N = 8e5+10;
int pa[N], a[N], lx[N];
int main(){
//ios::sync_with_stdio(0);
int n;
scanf("%d", &n);//cin>>n;
for(int i = 1; i <= n; i ++ )scanf("%d", a+i),lx[i] = a[i];
sort(lx+1,lx+1+n);
for(int i = 1; i <= n; i ++ )a[i] = lower_bound(lx+1,lx+1+n,a[i])-lx, pa[a[i]] = i;
int res = 0, pre = n+1;
for(int i = n; i >= 1; i -- ){
if(pa[i]<pre)res++;
pre = pa[i];
}
printf("%d\n", res);//cout<<res<<endl;
return 0;
}
C照看小猫
题意:
思路:
简单组合数学,
- 用桶排序预处理。
- 之后查看每个长度所能构成的解的个数,加入不够就break。
AC
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*
bool isprime(int x){
for(int i = 2; i<=x/i; i ++ )if(x%i==0)return false;
return true;
}
*/
const int N = 1e4+10;
int inv[N];
int fac[N];
const int mod = 77797;
typedef long long ll;
/*
void table(){
//for(int i = 1; i < N; i ++ )
}
*/
ll n, vis[20];
int main(){
//cout<<(isprime(77797));
ios::sync_with_stdio(0);
cin>>n;
int x;
for(int i = 1; i <= n; i ++ )cin>>x,vis[x]++;
ll ans = 1, sum = 0;
bool ok = true;
ll xx = 1;
for(int i = 1; i <= 10; i ++ ){
xx = xx*26;
//cout<<vis[i]<<endl;
sum += xx;
if(sum < vis[i]){
ok = false;
break;
}
for(int j = 1; j <= vis[i]; j ++ ){
ans = ans * (sum%mod) % mod;
sum -= 1;
}
}
if(ok)cout<<ans<<endl;
else cout<<-1<<endl;
return 0;
}
D路线规划
题意:
思路
建立最小生成树,就好。之后ans*2.
AC
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
const int M = N*10;
struct Edge{
int u, v;
ll w;
} e[M];
int f[N];
int find(int x){
if(x==f[x])return x;
return f[x] = find(f[x]);
}
int n, m;
void init(){
scanf("%d%d", &n, &m);//cin>>n>>m;
for(int i = 1; i <= m; i ++ ){
int u, v;
ll w;
scanf("%d%d%lld", &u, &v, &w);
e[i] = {
u,v,w};
}
}
void sol(){
sort(e+1,e+1+m,[&](Edge a, Edge b){
return a.w<b.w;
});
ll res = 0;
for(int i = 1; i <= n; i ++ )f[i] = i;
int tot = 1;
for(int i = 1; i <=m; i ++ ){
int u=e[i].u,v=e[i].v;
ll w = e[i].w;
int A = find(u), B = find(v);
if(A==B)continue;
f[A] = B;
res += w;
tot++;
if(tot==n)break;
}
printf("%lld\n", 2*res);
}
int main(){
init();
sol();
return 0;
}