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
还要继续努力辣!