NWRRC 2020题解

本场签到巨多,没写说明就是签到
A

#include <iostream>
#include <map>

std::map<int, std::string> mp;
void pre() {
mp[1995] = "ITMO";
mp[1996] = "SPbSU";
mp[1997] = "SPbSU";
mp[1998] = "ITMO";
mp[1999] = "ITMO";
mp[2000] = "SPbSU";
mp[2001] = "ITMO";
mp[2002] = "ITMO";
mp[2003] = "ITMO";
mp[2004] = "ITMO";
mp[2005] = "ITMO";
mp[2006] = "PetrSU, ITMO";
mp[2007] = "SPbSU";
mp[2008] = "SPbSU";
mp[2009] = "ITMO";
mp[2010] = "ITMO";
mp[2011] = "ITMO";
mp[2012] = "ITMO";
mp[2013] = "SPbSU";
mp[2014] = "ITMO";
mp[2015] = "ITMO";
mp[2016] = "ITMO";
mp[2017] = "ITMO";
mp[2018] = "SPbSU";
mp[2019] = "ITMO";
}

int main() {
	pre();
	int n;
	std::cin >> n;
	std::cout << mp[n];
	return 0;
}

B

#include <iostream>

using ll = long long;
int main() {
	int a, x, b, y, t;
	std::cin >> a >> x >> b >> y >> t;
	ll ans = 0;
	std::cout << a+21ll*x*(std::max(0, t-30)) << std::endl << b+21ll*y*std::max(0, t-45);


	return 0;
}

C
交互,没写,应该是签到
D

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define mod 1000000007
#define pb push_back
typedef pair<int,int> pir;
string sstr[]={"NO\n","YES\n"};
const int N=110;
int T,n,w,h,s;
char c[35][35];
char ch;
signed main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);
	cin>>n>>w>>h>>s;
	int mx=0;
	char mxpos;
	for(int i=1;i<=n;i++){
		cin>>ch;
		for(int j=1;j<=h;j++)
			for(int k=1;k<=w;k++){
				cin>>c[j][k];
			}
		for(int j=1;j<=h;j++){
			int tmp=0;
			char pre='.';
			for(int k=1;k<=w;k++){
				if(c[j][k]!=pre){
					tmp++;
					pre=c[j][k];
				}
			}
			if(pre=='#') tmp++;
			if(tmp>mx){
				mx=tmp;
				mxpos=ch;
			}
		}
	}
	int tot=(s-1)/mx+1;
	for(int i=0;i<tot;i++) cout<<mxpos;
}

E
一个比较麻烦的欧拉路题。首先对于1边组成的图,需要判断是否可能:
case1:所有点中,有且只能有1个点入度-出度为-1(且一定要为起点),有且只能有1个点入度-出度为1
case2:所有点入度-出度=0
不需要额外判连通,后面欧拉回路会判断的。
然后进行dfs求欧拉路,注意当前弧优化。
然后输出方案,需要特判当前数字只可能为 c c c,并且有不可行边的起点为 c c c的情形,是不符合题意的。

#pragma GCC optimize(3)
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <set>
#include <cassert>
const int N = 1e5+7;
bool vis[N];
int ans[N];
std::unordered_map<int, std::vector<int> > link;
int useless[N], cnt_u;
int cnt, _cnt, __cnt1, __cnt2;
std::unordered_map<int, int> mp;
int _ans[N];
int To[N], From[N];
void dfs(int node) {
	std::vector<int> &v = link[node];
	while (1) {
		while(!v.empty() && vis[v.back()]) v.pop_back();
		if (v.empty()) break;
		int tmp = v.back();
		vis[tmp] = 1;
		dfs(To[tmp]);
		ans[++cnt] = tmp;
	}
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	int n, c;
	std::cin >> n >> c;
	for (int i = 1, a, b, w; i<=n; ++i) {
		std::cin >> a >> b >> w;
		if (w) {
			link[a].push_back(i);
			To[i] = b;
			From[i] = a;
		} else {
			if (a==c) useless[++cnt_u] = i;
			else _ans[++_cnt] = i;
		}
	}
	dfs(c);
	std::reverse(ans+1, ans+1+cnt);
	for (int i = 1, now = c; i<=cnt; ++i) {
		if (From[ans[i]]!=now) {
			std::cout << "No\n";return 0;
		}
		_ans[++_cnt] = ans[i];
		now = To[ans[i]];
		if (now!=c) {
			for (int j = 1; j<=cnt_u; ++j) _ans[++_cnt] = useless[j];
			cnt_u = 0;
		}
	}
	if (_cnt<n || cnt_u>0) {
		std::cout << "No\n";return 0;
	}
	std::cout << "Yes\n";
	for (int i = 1; i<=_cnt; ++i) std::cout << _ans[i] << " ";
	std::cout << std::endl;
	return 0;
}

F

#include<iostream>
#include<cmath>

#define maxn 3003
#define eps 1e-8
#define zps 1e-4

#define lint int64_t

using
		namespace
					std;

int n;
double P;
lint a[maxn];
lint d[maxn];
lint s[maxn];
lint s2[maxn];
int kotae_pos,kotae_neg;

double dabs(double x){
	
	return x<0.?-x:x;
}

void check(int l,int r){
	
	lint ds=s[r]-s[l-1];
	lint ds2=s2[r]-s2[l-1];
	lint len=r-l+1;
	
	lint nu=ds*ds;
	lint de=ds2*len-ds*ds;
	
	if(de==0){
		
		if(ds>0){
			
			kotae_pos++;
		}
		if(ds<0){
			
			kotae_neg++;
		}
	}
	else{
		
		if(nu>=de*P*P){
			
			if(ds>0){
				
				kotae_pos++;
			}
			if(ds<0){
				
				kotae_neg++;
			}
		}
	}
}

signed main(){
	
	cin>>n>>P;
	
	P-=eps;
	
	for(int i=1;i<=n;i++){
		
		cin>>a[i];
		
		d[i]=a[i]-a[i-1];
		s[i]=s[i-1]+d[i];
		s2[i]=s2[i-1]+d[i]*d[i]; 
	}
	
	for(int i=2;i<=n;i++){
		
		for(int j=i+1;j<=n;j++){
			
			check(i,j);
		}
	}
	
//	for(int i=2;i<=n;i++){
//		
//		if(a[i]>a[i-1]){
//			kotae_pos++;
//		}
//		if(a[i]<a[i-1]){
//			kotae_neg++;
//		}
//	}
	
	cout<<kotae_pos<<' '<<kotae_neg<<endl;
	
end:
	return EOF+1;
}

G
整体思路较为简单,就是一个BFS,相较于floyd,其多出了顺序性,因此不能用简单的循环,还需要额外枚举边上的字符即可。
比赛的时候C语言写的一直WA,结果似乎是因为溢出

import java.util.*;
import java.io.*;
import java.math.BigInteger;

class Node {
	
	public Integer u;
	public Integer v;
	public Integer x;
	public BigInteger len;
	
	Node(Integer u_,Integer v_,Integer x_,BigInteger len_){
		
		u = u_;
		v = v_;
		x = x_;
		len = len_;
	}
}

public class Main {
	
	public static Integer trans(char c) {
		
		if(c >= 'A' & c <= 'Z') {
			
			return c - 'A';
		}
		else if(c >= 'a' & c <= 'z') {
			
			return c - 'a';
		}
		
		return -1;
	}
	
	static Integer p = 0, n = 0, m = 0, s = 0, t = 0;
	
	static Boolean big[][][] = new Boolean[30][30][30];
	static Boolean small[][] = new Boolean[30][30];
	static BigInteger edge[][][] = new BigInteger[30][30][30];
	
	static Queue<Node> q = new LinkedList();
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		
		for(int i = 0;i < 30;i+=1)
			for(int j = 0;j < 30;j+=1) {
				small[i][j] = false;
				for(int k = 0;k < 30;k+=1) {
					
					big[i][j][k] = false;
					edge[i][j][k] = BigInteger.ZERO;
				}
			}
				
		
		p = in.nextInt();
		
		for(Integer i = 1;i <= p;i+=1) {
			
			String s = in.next();
			String t = in.next();
			t = in.next();
			//System.out.println(s);
			//System.out.println(t);
			
			if(t.length() == 1) {
				
				small[trans(s.charAt(0))][trans(t.charAt(0))]=true;
			}
			else if(t.length() == 2) {
				
				big[trans(s.charAt(0))][trans(t.charAt(0))][trans(t.charAt(1))]=true;
			}
		}
		
		n = in.nextInt();
		m = in.nextInt();
		s = in.nextInt();
		t = in.nextInt();
		
		for(int i = 1;i <= m;i+=1) {
			
			int u,v;
			char x;
			
			u = in.nextInt();
			v = in.nextInt();
			x = in.next().charAt(0);
			
			for(int j = 0;j < 26;j+=1) {
				
				if(small[j][trans(x)]) {
					
					edge[u][v][j] = BigInteger.ONE;
					q.add(new Node(u,v,j,BigInteger.ONE));
				}
			}
		}
		
		while(!q.isEmpty()) {
			
			//System.out.println(q.size());
			
			Node tem = q.element();
			q.remove();
			
			int i = tem.u;
			int k = tem.v;
			int ci = tem.x;
			
			for(int cn = 0;cn < 26;cn+=1) {
				
				for(int cj = 0;cj < 26;cj+=1) {
					
					if(!big[cn][ci][cj]) continue;
					
					for(int j = 1;j <= n;j+=1) {
						
						if(edge[i][k][ci].compareTo(BigInteger.ZERO) == 1 & edge[k][j][cj].compareTo(BigInteger.ZERO) == 1) {
							
							BigInteger nxt = edge[i][k][ci].add(edge[k][j][cj]);
							if(edge[i][j][cn].compareTo(nxt) == 1 | edge[i][j][cn].equals(BigInteger.ZERO)) {
								
								edge[i][j][cn] = nxt;
								q.add(new Node(i,j,cn,edge[i][j][cn]));
							}
						}
					}
				}
			}
			
			for(int cn = 0;cn < 26;cn+=1) {
				
				for(int cj = 0;cj < 26;cj+=1) {
					
					if(!big[cn][cj][ci]) continue;
					
					for(int j = 1;j <= n;j+=1) {
						
						if(edge[j][i][cj].compareTo(BigInteger.ZERO) == 1 & edge[i][k][ci].compareTo(BigInteger.ZERO) == 1) {
							
							BigInteger nxt = edge[j][i][cj].add(edge[i][k][ci]);
							if(edge[j][k][cn].compareTo(nxt) == 1 | edge[j][k][cn].equals(BigInteger.ZERO)) {
								
								edge[j][k][cn] = nxt;
								q.add(new Node(j,k,cn,edge[j][k][cn]));
							}
						}
					}
				}
			}
		}
		
		BigInteger kotae = edge[s][t]['S'-'A'];
		
		if(kotae.equals(BigInteger.ZERO)){
			
			System.out.println("NO");
		}
		else {
			
			System.out.println(kotae);
		}
	}

}

H
下次一定
I

#include<iostream>


using
		namespace
					std;

int s;

signed main(){
	
	cin>>s;
	
	for(int i=0;i<=1000;i++){
		
		for(int j=0;j<=1000;j++){
			
			if(i*i+j*j==s){
				
				printf("%d %d\n",0,0);
				printf("%d %d\n",i,j);
				printf("%d %d\n",-j,i);
				printf("%d %d\n",i-j,i+j);
				goto end;
			}
		}
	}
	
	printf("Impossible\n");
	
end:
	return EOF+1;
}

J,K
HOJ没写SPJ,本身也不太可写
L
签到交互。
M

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define mod 1000000007
#define pb push_back
typedef pair<int,int> pir;
string sstr[]={"NO\n","YES\n"};
const int N=200010;
int T,n,m;
int a[N];
int mi=0,mx=inf;
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		mi=max(mi,a[i]-a[i-1]);
	}
	for(int i=2;i<=n;i++){
		mx=min(mx,a[i]-a[i-2]-1);
	}
	if(mx>=mi){
		cout<<mx<<'\n';
	}
	else cout<<0;
}

N
如果黑色数量恰好有 k / 2 k/2 k/2个,那么需要用到两根,数量*2.
否则,只需要1根即可。
注意有黑色的范围,如果 k > n k>n k>n,则不需要用到黑色较小的木棒,转化为针对白色的方案数进行统计即可。
注意需要统计出对称和不对称的数量,并对不对称的数量/2才是本质不同的木棒数量。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lint ll
#define int ll
lint C(lint a,lint b){
	
	if(a<0||b<0||b>a) return 0;
	if(b>a-b) b=a-b;
	
	lint ans=1;
	
	for(int i=1;i<=b;i++){
		
		ans*=(a-i+1);
		ans/=i;
	}
	
	return ans;
}

signed main()
{
	int n,k;
	int ans=0;
	cin>>n>>k;
	if(k>n) k=2*n-k;
	for(int i=0;i<=k;i++){//有i个黑色
		int tot=C(n,i);//总共的方案数
		int dc=0;//对称的方案数
		if(i%2==0||n%2==1) dc=C(n/2,i/2);
		int ndc=tot-dc;//不对称的方案数
		if(2*i!=k) ans+=dc+ndc/2;
		else ans+=tot+dc;//对称的需要额外一个
	}
	cout<<ans<<'\n';
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值