大连海事大学ACM校赛热身赛题解

热身赛

A 熊熊的爱

问题描述

输出一元二次方程 x 2 + 794 x − 683280 = 0 x^2+794x-683280=0 x2+794x683280=0 的解

思路简介

二元一次方程公式求解

赛中发现speci judge出了问题,八点十五才检查出来,非常抱歉。

参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
const int inf=0x3f3f3f3f;
const int maxn=1e5+5;
const int N=6e6+5;
const LL mod=998244353;
const double pi=acos(-1);
int main()
{
    int p=520,q=1314;
    printf("%d %d",p,-q);
}

B 井字格

问题描述

小智十分喜欢下棋,这一天小智和他的同学在下井字棋。
井字棋是在3*3格子上进行的连珠游戏, 两个游戏者轮流在格子里留下标记(先手者为X,后手为O),任意三个标记形成一条直线,则为获胜。
遗憾的是小智和他的同学都不知道井字棋的游戏规则,所以他俩下满九个格子也不知道应该判谁赢
现在给9个数字,代表两人的下棋过程,每个数字对应的棋盘位置如图所示。
判断最后结果,如果为先手胜利则输出1,后手胜利则输出0,平局则输出-1 。
注意:一局游戏如果有任意一方三个标记连成直线则判定为其赢,无论后面的标记如何。

思路简介

模拟

参考代码
#include <bits/stdc++.h>
using namespace std;
int edge[5][5];
int check(int x)
{
	int flag;
	for(int i=1;i<=3;i++){
		flag=0;
		for(int j=1;j<=3;j++) 	flag+=(edge[i][j]==x);
		if(flag==3) return 1;
	}
	for(int j=1;j<=3;j++){
		flag=0;
		for(int i=1;i<=3;i++) 	flag+=(edge[i][j]==x);
		if(flag==3) return 1;
	}
	flag=0;
	for(int i=1;i<=3;i++)
		flag+=(edge[i][i]==x);
	if(flag==3) return 1;
	flag=0;
	for(int i=1;i<=3;i++)
		flag+=(edge[i][3-i+1]==x);
	if(flag==3) return 1;
	return 0;
}
int main()
{
	int T,a,x,y,ans;
	cin>>T;
	while(T--)
	{
		memset(edge,-1,sizeof(edge));
		ans=-1;
		for(int i=1;i<=9;i++)
		{
			cin>>a;
			x=(a+2)/3;y=(a+2)%3+1;
			edge[x][y]=i%2;
			if(ans==-1&&check(i%2)) ans=i%2;
		}
        printf("%d\n",ans);
    }
    return 0;
}

C 数字字符串

问题描述

给出长度为N的由 ‘1’ 到 ’9‘ 组成数字字符串S与正整数P,求字符串S子串中所表示的十进制数为P的倍数的个数。
子串:串中任意个连续的字符组成的子序列称为该串的子串
表示规则示例如下:
对于字符串S=“45216” 以及正整数P=26
仅有子串 "52"所表示的52为26的倍数,是合法答案,故结果为1。

思路简介

动态规划
可以先想一下这个题的简化版本,给出一个长度为n的数列 a 1 , a 2 , a 3 , . . , a n a_1,a_2,a_3,..,a_n a1,a2,a3,..,an与正整数p,求该数列的连续的子序列所表示的和是p的倍数的连续子序列个数。那么设数组dp[n],对于dp[x][y]=z,z就代表以第 a x a_x ax为结尾的连续子序列的和对p取模的个数。为什么要这么设置呢,举个例子,如果 a 2 + a 3 + a 4 + a 5 a_2+a_3+a_4+a_5 a2+a3+a4+a5的和模p为5,且 a 4 + a 5 a_4+a_5 a4+a5的和模p为5,那么 a 2 + a 3 a_2+a_3 a2+a3的和就是p的倍数,这个题可以由此进一步展开。

参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
int n,p,t;
int dp[maxn][505];
LL cnt=0;
char s[maxn];
int main()
{
    scanf("%d%d",&n,&p);
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
    {
        dp[i][(s[i]-'0')%p]=1;
        for(int j=0;j<p;j++)
            dp[i][ (j*10+(s[i]-'0'))%p ]+=dp[i-1][j];
    }
    for(int i=1;i<=n;i++)
        cnt+=dp[i][0];
    printf("%lld\n",cnt);
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值