3-28新星赛模拟赛

3-28新星赛模拟赛题解

原题目
题目
AC了8个题qwq 还要继续努力鸭!
7-1 factorial
题意:求一个数字阶乘的位数。
主要考察求一个数的位数的公式~ x=(int)lg(a)+1。
大数阶乘可以看这个
由对数的公式: lg(1* 2 * 3 *…*n)=lg(1)+lg(2)+lg(3)+…+lg(n)
注意要用double存yo !

#include<cstdio>
#include<cmath>
#define db double
int main(){
	int t,n;
	db sum;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		sum = 0;
		for(int i = n; i > 0; --i)
			sum += log10(i);
		printf("%d\n",(int)sum + 1);
	}
	return 0;
} 

7-2 exam
题意:If the scores of two students are different, the first course with different scores will be the basis for ranking, and the one with higher scores will come first.按照题意模拟即可。注意是第一科不同就可,不是看总分。

#include<cstdio>
#include<algorithm>
using namespace std;
int n,k;
struct stu{
	int id;
	int score[15];
}s[1005];
int cmp(stu s1,stu s2){
	int i;
	for(i = 0; i < k && s1.score[i] == s2.score[i]; ++i);
	if(i == k)	return s1.id < s2.id;
	else	return s1.score[i] > s2.score[i];
}
int main(){
	scanf("%d%d",&n,&k);
	for(int i = 1; i <= n; ++i){
		scanf("%d",&s[i].id);
		for(int j = 0; j < k; ++j)
			scanf("%d",&s[i].score[j]);
	}
	sort(s + 1,s + 1 + n,cmp);
	for(int i = 1; i <= n; ++i)
		printf("%d ",s[i].id);
	return 0;
}

7-3 stack
题意:栈的模拟。只是输出的时候从栈底开始输出。我是用一个栈帮助另一个栈输出~

#include<cstdio>
#include<stack>
using namespace std;
int n,x,command;
stack<int> s,t;
int main(){
	scanf("%d",&n);
	for(int i = 1; i <= n; ++i){
		scanf("%d%d",&command,&x);
		if(command == 1){
			s.push(x); 
		}else{
			for(int i = 1; i <= x; ++i)
				s.pop();
		}
	}
	printf("%d\n",s.size());
	while(s.size()){
		t.push(s.top()); 
		s.pop();
	}
	while(t.size()){
		printf("%d ",t.top());
		t.pop();
	}
	return 0;
}

7-4 Hateful fat
题意:给三个点,判断点的位置。这个题看起来比较麻烦,其实没有什么啦!
注意斜率尽量不要算出来,而是用乘法的形式进行转换。因为可能会有斜率不存在的情况,而转换成乘法依然成立(因为两个分母都是0,乘法仍然相等)。注意最后三种情况的转化,考虑到斜率不存在/斜率为0的情况,是或而不是且的关系。(P.S.这个题是唯一一个拿到一血的题)

#include<cstdio>
#include<algorithm>
using namespace std;
int p0x,p0y,p1x,p1y,p2x,p2y,n,temp1,temp2;
int main(){
	scanf("%d%d%d%d",&p0x,&p0y,&p1x,&p1y);
	scanf("%d",&n);
	while(n--){
		scanf("%d%d",&p2x,&p2y);
		temp1 = (p1y - p0y) * (p2x - p0x),temp2 = (p2y - p0y) * (p1x - p0x);
		if(temp1 == temp2){
			if(p2x > max(p1x,p0x) || p2y > max(p1y,p0y))	printf("ONLINE_FRONT\n");
			else if(p2x < min(p1x,p0x) || p2y < min(p1y,p0y))	printf("ONLINE_BACK\n");	
			else printf("ON_SEGMENT\n");
		}else{
			if(temp1 > temp2)	printf("CLOCKWISE\n");
			else printf("COUNTER_CLOCKWISE\n");
		}
	}
	return 0;
}

7-5 prime
题意:求1-N有多少素数。标准的素数筛法。
下面是一个标准的欧拉线性素数筛:

bool prime[maxn];
vector<int> primes;
void make_prime(int n)
{
    memset(prime,1,sizeof(prime));
    for (int i = 2;i <= n;i++)
    {
        if (prime[i])
            primes.push_back(i);
        for (int p : primes)
        {
            if (p * i > n)
                break;
            prime[p * i] = 0;
            if (i % p == 0)
                break;
        }
    }
}

比赛的时候用的普通素数筛,也能过:

#include<cstdio>
#include<cstring>
#define ll long long 
#define MAX 10000000 
using namespace std;
ll su[MAX],cnt,n,ans;
bool isprime[MAX];
void prime(){
    cnt = 1;
    memset(isprime,1,sizeof(isprime));
    isprime[0] = isprime[1] = 0;
    for(ll i = 2;i <= MAX;i++){
        if(isprime[i])
            su[cnt++] = i;
        for(ll j = i * 2; j <= MAX; j += i)
            isprime[j]=0;
    }
}
int main(){
    prime();
    scanf("%lld",&n);
    for(ll i = 2; i <= n; i++)
        if(isprime[i])
        	ans++;
    printf("%lld",ans);
    return 0;
}

7-6 lcy‘s weight
题意:高精度板子。不想说啥了QWQ(要是自己写肯定会被恶心到)可能不是最好的板子?随便用了一个
Java天下第一

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int n,x;
string wei,buff;
int cmp(string str1,string str2){
    if(str1.length() > str2.length()) return 1;
    else if(str1.length() < str2.length())  return -1;
    else return str1.compare(str2);
}
string add(string str1,string str2){		//+
    string str;
    int len1 = str1.length();
    int len2 = str2.length();
    if(len1 < len2){
        for(int i = 1; i <= len2 - len1; i++)
           str1 = "0" + str1;
    }
    else{
        for(int i = 1; i <= len1 - len2; i++)
           str2 = "0"+str2;
    }
    len1 = str1.length();
    int buff = 0,temp = 0;
    for(int i = len1 - 1; i >= 0; i--){
        temp = str1[i] - '0' + str2[i] - '0' + buff;
        buff = temp / 10;
        temp %= 10;
        str = (char)(temp + '0') + str;
    }
    if(buff != 0)  str =(char)(buff + '0') + str;
    return str;
}
string sub(string str1,string str2){		//-
    string str;
    int temp = str1.length() - str2.length(),buff = 0;
    for(int i = str2.length() - 1; i >= 0; i--){
        if(str1[temp + i] < str2[i] + buff){
            str = (char)(str1[temp + i] - str2[i] - buff + '0' + 10) + str;
            buff = 1;
        }
        else{
            str = (char)(str1[temp + i] - str2[i] - buff + '0') + str;
            buff = 0;
        }
    }
    for(int i = temp - 1; i >= 0; i--){
        if(str1[i] - buff >= '0'){
            str = (char)(str1[i]-buff)+str;
            buff = 0;
        }
        else{
            str = (char)(str1[i] - buff + 10) + str;
            buff = 1;
        }
    }
    for(int i = 0; str[i] == '0'; ++i)	str.erase(0,1); 
    return str;
}
int a[10005],b[10005],c[10005],len;
string muliply(string str1,string str2){        //*
	memset(c,0,sizeof(c));
	string str = "";
    int len1 = str1.length();
    int len2 = str2.length();
    for(int i = 1; i <= len1; i++)	a[i] = str1[len1 - i] - '0';
    for(int i = 1; i <= len2; i++)	b[i] = str2[len2 - i] - '0';
    for(int i = 1; i <= len2; i++)
    	for(int j = 1; j <= len1; j++)
    		c[i + j - 1] += a[j] * b[i];
    for(int i = 1; i < len1 + len2; i++)
    	if(c[i] > 9){
    	    c[i + 1] += c[i] / 10;
     	    c[i] %= 10;
    	}
    len = len1 + len2;
    while(c[len] == 0 && len > 1)	len--;
    for(int i = len; i >= 1; i--)
    	str += c[i] + '0';
    return str;
}
int main(){
	cin >> n >> wei;
	for(int i = 1; i <= n; ++i){
		cin >> x >> buff;
		if(x == 1)	wei = add(wei,buff);
		else if(x == 2)	wei = sub(wei,buff);
		else wei = muliply(wei,buff);
	}
	cout << wei;
	return 0;
}

7-7 Prepare for CET-6
题意:字典树(虽然我不会orz)
我是排序做的,显然并不是正确的算法。例如数据给出4 2 a ab ab ac 答案是1+2=3,而不是1+1=2.(a ac一组, ab ab一组,而不是字典序)。
下面放出错误代码:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int n,k,t,ans;
string s[100005];
int solve(int x){
	int i,j;
	for(i = 0; ; ++i){
		for(j = x + 1; j < k + x; ++j){
			if(s[j][i] != s[j - 1][i])	return i;
			if(s[j][i] == '\0')	return i;
		}
	}
}
int main(){
	scanf("%d",&t);
	for(int i = 1; i <= t; ++i){
		ans = 0;
		scanf("%d%d",&n,&k);
		for(int j = 1; j <= n; ++j)
			cin >> s[j];
		sort(s + 1,s + 1 + n);
		for(int j = 1; j <= n; j += k)
			ans += solve(j);
		printf("Case #%d: %d\n",i,ans);
	}
	return 0;
}

放一个链接8 字典树的解法
字典树解法!
7-8 Computer Games
太长不看!博弈论的题QWQ……有时间看看8
7-9 sort
签到题。sort排序。

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,x,a[1000005];
int cmp(int x,int y){
	return x > y;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; ++i)
		scanf("%d",&a[i]);
	sort(a + 1,a + 1 + n,cmp);
	for(int i = 1; i <= m; ++i)
		printf("%d ",a[i]);
	return 0;
}

7-10 lcy eats biscuits
题意:求吃完所有饼干的最小距离。
其实是洛谷的原题……原题我这么写是过不了的,因为n比14大。这个题数据小~所以dfs+剪枝也可以过。正解貌似是状态压缩dp(撞鸭) 不会orz

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
bool vis[20];
int n;
struct pos{
	double x,y;
}p[20];
double ans = 0x3f3f3f3f,dis[20][20];
void dfs(int now, int step, double nowans){
	if(step == n + 1){
		ans = min(ans,nowans);
		return ;
	}
	for(int i = 1; i <= n; ++i){
		if(!vis[i] && nowans + dis[now][i] < ans){
			vis[i] = 1;
			dfs(i,step + 1,nowans + dis[now][i]);
			vis[i] = 0;
		}
	}
}
int main(){
	scanf("%d",&n);
	for(int i = 1; i <= n; ++i)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	p[0].x = 0.0,p[0].y = 0.0;
	for(int i = 0; i <= n; ++i){
		for(int j = 0; j <= n; ++j){
			if(i == j)	dis[i][j] = 0;
			else dis[i][j] = dis[j][i] = sqrt((p[i].x - p[j].x) * (p[i].x - p[j].x) + (p[i].y - p[j].y) * (p[i].y - p[j].y));
		}
	}
	dfs(0,1,0);
	printf("%.2lf",ans);
	return 0;
}

毕竟是新星赛 板子题比较多啦!
求一个数的位数(1)、素数打表(5)、高精度(6)、字典树(7)都是模板题;
(3)是数据结构的应用,(2)(9)是排序;
(4)比较考验数学知识(??);
(8)(10)应该是比较难的两个题了8~如果数据不放水的话10是通不过的QWQ
还要继续努力辣!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值