2015NEERC Northern Sub 解题报告

A. Alex Origami Squares

解法:分类讨论

Code:

int main()
{
	freopen("alex.in","r",stdin);
	freopen("alex.out","w",stdout);
	double a,b;scanf("%lf%lf",&a,&b);
	if(a > b)  swap(a,b);
	double m1 = a  / 2.000;
	double ans = m1;
	double m2  = b / 3.0;
	if(m2 <= a) ans = max(ans,m2);
	else ans = max(ans,a);
	printf("%.3f\n", ans);	
	return 0;
}

B. Black and White

解法:构造

Code:

int main(){
	freopen("black.in","r",stdin);
	freopen("black.out","w",stdout);
	int b,w;scanf("%d %d",&b,&w);
	if(b == w){
		printf("1 %d\n", b + w);
		for(int i = 1;i <= b + w;++i){
			if(i & 1) printf("@");else printf(".");
		}
		printf("\n");
	} else if(b > w){
		swap(b,w);
		int n = 2;
		int m = (b - 1) * 2 + (w - (b-1)) * 2;
		printf("%d %d\n", n,m);
		for(int i = 1;i <= (b - 1) * 2;++i){
			if(i & 1) printf("."); else printf("@");
		}
		for(int i = 1;i <= (w - (b-1)) * 2;++i) printf(".");
		printf("\n");
		for(int i = 1;i <= m;++i){
			if(i & 1) printf("."); else printf("@");
		}
		printf("\n");
	} else{
		int n = 2;
		int m = (b - 1) * 2 + (w - (b-1)) * 2;
		printf("%d %d\n", n,m);
		for(int i = 1;i <= (b - 1) * 2;++i){
			if(i & 1) printf("@"); else printf(".");
		}
		for(int i = 1;i <= (w - (b-1)) * 2;++i) printf("@");
		printf("\n");
		for(int i = 1;i <= m;++i){
			if(i & 1) printf("@"); else printf(".");
		}
		printf("\n");
	}
	return 0;
}

C. Concatenation

解法:先求出每种字母在 S1 ( 除 i 1 ) (除i_1) (i1) 和 S2 ( 除 i m ) (除i_m) (im) 中的数量,其贡献 = c n t 1 [ c h ] ∗ c n t 2 [ c h ] = cnt1[ch] * cnt2[ch] =cnt1[ch]cnt2[ch],最后求和即可。

Code:

string s1,s2;
int cnt1[30],cnt2[30];
int main(){
	freopen("concatenation.in","r",stdin);
	freopen("concatenation.out","w",stdout);
	cin >> s1 >> s2;
	reverse(s2.begin(),s2.end());
	int n1 = s1.length(),n2 = s2.length();
	ll res = 1ll * n1 * n2;
	for(int i = 1;i < n1;++i) cnt1[s1[i] - 'a']++;
	for(int i = 1;i < n2;++i) cnt2[s2[i] - 'a']++;
	for(int i = 0;i < 32;++i){
		res -= 1ll * cnt1[i] * cnt2[i];
	}
	printf("%lld\n", res);
}

D. Distribution in Metagonia (待补)

E - Easy Arithmetic

解法:正数不变,负数则转变为 − - 第一位 + + + 从第二位开始的数, 注意处理前导零

Code:

char s[MX];
char ans[MX];
int main()
{
	freopen("easy.in","r",stdin);
	freopen("easy.out","w",stdout);
	scanf("%s",s);
	int p = 0;
	int n = strlen(s);

	for(int i = 0;i < n;++i){
		ans[p++] = s[i];
		if(s[i] == '-' && (i + 2 < n && s[i+2] <= '9' && s[i+2] >= '0')){
			int j = i + 2;
			ans[p++] = s[i+1];
			while(s[j] == '0' && j < n){
				ans[p++] = '+';ans[p++] = s[j];j++;
			}
			if(s[j] == '-' || s[j] == '+' || j == n){
				i = j - 1;
			} else{
				ans[p++] = '+';
				while(j < n && s[j] <= '9' && s[j] >= '0'){
					ans[p++] = s[j];j++;
				}
				i = j - 1;
			}
		}
	}
	printf("%s\n", ans);
	return 0;
}

F. Fygon(待补)

G. Graph(待补)

H. Hash Code Hacker (待补)

I. Insider’s Information(待补)

J. Journey to the “The World’s Start”

解法:二分 + 单调队列优化dp

Code:

int n,t;
int p[MX];
int d[MX];
ll que[MX],dp[MX];
bool judge(int k){
	clr(dp,0);
	int head = 0,tail = 1;
	dp[1] = 0;
	que[head] = 1;
	for(int i = 2;i <= n;++i){
		dp[i] = dp[que[head]] + d[i];
		while(head < tail && dp[que[tail-1]] >= dp[i]) tail--;
		que[tail++] = i;
		while(head < tail && que[tail-1] - que[head] + 1 > k) head++;
	}
	return dp[n] <= 1ll * t;
}

int main()
{
	freopen("journey.in","r",stdin);
	freopen("journey.out","w",stdout);
	scanf("%d %d",&n,&t);t -= (n - 1);
	for(int i = 1;i < n;++i) scanf("%d",&p[i]);
	for(int i = 2;i < n;++i) scanf("%d",&d[i]);
	int l = 1,r = n - 1;
	while(l < r){
		int mid = (l + r) >> 1;
		if(judge(mid)) {r = mid;}
		else l = mid + 1;
	}
	int res = p[l];
	for(int i = l+1;i < n;++i) res = min(res,p[i]);
	printf("%d\n", res);
	return 0;
}

K. Kingdom Trip(待补)

L. Lucky Chances

解法:维护前后缀最大值即可

Code:

int prer[MX][MX], sufr[MX][MX];
int prec[MX][MX], sufc[MX][MX];
int mp[MX][MX];
int main()
{
	freopen("lucky.in","r",stdin);
	freopen("lucky.out","w",stdout);
	int n,m;scanf("%d %d",&n,&m);
	for(int i = 1;i <= n;++i){
		for(int j = 1;j <= m;++j){
			scanf("%d",&mp[i][j]);
			prer[i][j] = max(prer[i][j-1] , mp[i][j]);
		}
	}
	for(int j = 1;j <= m;++j)
		for(int i = 1;i <= n;++i) prec[i][j] = max(prec[i-1][j] , mp[i][j]);
	for(int i = 1;i <= n;++i)
		for(int j = m;j >= 1;--j) sufr[i][j] = max(sufr[i][j+1] , mp[i][j]);
	for(int j = 1;j <= m;++j)
		for(int i = n;i >= 1;--i) sufc[i][j] = max(sufc[i+1][j] , mp[i][j]);
	int res = 0;
	for(int i = 1;i <= n;++i){
		for(int j = 1;j <= m;++j){
			int u = mp[i][j];
			if(prer[i][j-1] < u) res++;if(sufr[i][j+1] < u) res++;
			if(prec[i-1][j] < u) res++;if(sufc[i+1][j] < u) res++;
		}
	}
	printf("%d\n", res);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值