【思特奇杯·云上蓝桥·算法集训营】第四周

1.门牌制作

【问题描述】
小蓝要为一条街的住户制作门牌号。
这条街一共有2020位住户,门牌号从1到2020编号。
小蓝制作门牌的方法是先制作0到9这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌1017需要依次粘贴字符1、0、1、7,即需要1个字符0,2个字符1,1个字符7。
请问要制作所有的1到2020号门牌,总共需要多少个字符2?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

答案:624

#include<stdio.h>
int main()
{
	int sum=0,p,q;
	
	for( q=1;q<=2020;q++)
	{
		p=q;
		while(p)
		{
			if(p%10==2)
			{
				sum++;
			}
			p/=10;
		}
	}
	printf("%d",sum);
	return 0;
}

2.既约分数

答案:2481215

#include<stdio.h>

int d(int m, int n)
{
	if (m % n == 0)
	{
		return n;
	}
	else
	{
		return d(n, m % n);
	}
 
	
}
int main()
{
	int count = 0;
	for (int i = 1; i <= 2020; i++)
	{
		for (int j = 1; j <= 2020; j++)
		{
			if (d(i, j) == 1)
			{
				count += 1;
				
			}
		}
	}
	printf("%d", count);
 
	}

3.蛇形排列

答案:671

#include<stdio.h>
 
int main()
{
	
	int n = 20 * 2 - 1;
	
	int a = 0;
	int b = 0;
	for (int i = 1; i <= n; i++)
	{
		a += i;
	}
	b = (a + a - n + 1) / 2;
	printf("%d ", b);
	return 0;
 
}

4.跑步锻炼

答案:8879

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    int a=0;
    int m=6; 
    int monthes[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};

    for(int i=2000; i<=2020; i++)
    {
        if((i%4==0&&i%100!=0)||(i%400==0))
        {
            monthes[2]=29;  
        }
        else
        {
            monthes[2]=28;  
        }
        for(int month=1; month<=12; month++)
        {
            for(int day=1; day<=monthes[month]; day++)
            {
                a++;
                if(m==8)
                {
                    m=1;
                }
                if(m==1||day==1)
                {
                    a++;
                }
                m++;
                if(i==2020&&month==10&&day==1)
                {
                    printf("%d",a);
                }
            }
        }
    }
    return 0;
}

5.七段码

答案:80

#include<iostream>
#include<set>
#include<cstring>
using namespace std;

int ve[7][7];
bool visit[7];
int ans = 0;
set <set <int> > se;
void dfs(int x,set<int> s)
{
  if(!se.count(s))
  {
    se.insert(s);
    ans++;
  }
  if(s.size() == 7)
  return;
  for(int j = 0; j < 7; j++)
  {
    if(visit[j] || !ve[x][j]) continue;
    s.insert(j);
    visit[j] = 1;
    dfs(j,s);
    visit[j] = 0;
    s.erase(j);
  }
}
void add(int x, int y)
{
  ve[x][y] = 1;
  ve[y][x] = 1;
}
int main()
{
  
  add(0,1);
  add(0,5);
  
  add(1,6);
  add(1,2);
  
  add(2,6);
  add(2,3);
  
  add(3,2);
  add(3,4);
  
  add(4,5);
  add(4,6);
  
  add(5,6);
  set<int> s;
  for(int i = 0; i <= 6; i++)
  {
    s.insert(i);
    visit[i] = 1;
    dfs(i,s);
    visit[i] = 0;
    s.erase(i);
  }
  cout<<ans<<endl;
  return 0;
}

6.成绩统计

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
    int sum,temp;
    float p,excellence;
    int psum=0,excellencesum=0;
    scanf("%d",&sum);
    for(int i=1; i<=sum; i++)
    {
        scanf("%d",&temp);
        if(temp>=60)
        {
            psum++;  
        }
        if(temp>=85)
        {
            excellencesum++; 
        }
    }
    p=(float)psum/sum*100;  
    excellence=(float)excellencesum/sum*100;  
    int a=(int)(p+0.5);  
    int b=(int)(excellence+0.5);
    printf("%d%%\n%d%%",a,b);  
    return 0;
}

7.回文日期

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
    int sum,temp;
    float p,excellence;
    int psum=0,excellencesum=0;
    scanf("%d",&sum);
    for(int i=1; i<=sum; i++)
    {
        scanf("%d",&temp);
        if(temp>=60)
        {
            psum++;  
        }
        if(temp>=85)
        {
            excellencesum++; 
        }
    }
    p=(float)psum/sum*100;  
    excellence=(float)excellencesum/sum*100;  
    int a=(int)(p+0.5);  
    int b=(int)(excellence+0.5);
    printf("%d%%\n%d%%",a,b);  
    return 0;
}

8.子串数值和(参考)

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
char s[N];
ll f[N];    
int last[30];
int main(){
    scanf("%s",s+1);
    int n = strlen(s+1);
    ll ans = 0;
    
    for(int i=1;i<=n-i+1;i++)f[i] = f[n-i+1] = (n-i+1)*(ll)i; 
    for(int i = 1;i<=n;i++){
        int t = s[i]-'a';
        if(!last[t]){    
            ans += f[i];
        }else{
            ans += f[i] - f[i]/i*last[t]; 
        }
        last[t] = i; 
    }
    printf("%lld",ans);
    return 0;
}

9.平面切分

#include<iostream>
#include<cmath>
#define max_size 1010

using namespace std;
int ans=1;
double jd[max_size][2];

void f(int i,int arr[1010][2],int a,int b)
{
    int temp=0;
    for(int j=1;j<i;j++)
    {
        if(arr[j][0]==a)
        {
            if(arr[j][1]==b) return;
            else continue;
        }
        else
        {
            jd[temp][0]=(b-arr[j][1])*1.0/(arr[j][0]-a);
            jd[temp][1]=a*1.0*jd[temp][0]+b;
            int flag=1;
            for(int k=0;k<temp;k++)
            {
                if(abs(jd[k][0]-jd[temp][0])<1e-6&&abs(jd[k][1]-jd[temp][1])<1e-6)
                {
                    flag=0;
                    break;
                }
            }
            if(flag==1)
            {
                temp++;
            }
        }
    }
    ans=ans+temp+1;
int main()
{
    int num;
    cin>>num;
    int arr[1010][2];
    for(int i=1;i<=num;i++)
    {
        cin>>arr[i][0]>>arr[i][1];
        f(i,arr,arr[i][0],arr[i][1]);
    }
    cout<<ans;
    return 0;
}

9.平面切分

#include<iostream>
#include<cmath>
#define max_size 1010

using namespace std;
int ans=1;//没有直线时有一个平面
double jd[max_size][2];//交点可能含小数,故用float型

void f(int i,int arr[1010][2],int a,int b)
{
    int temp=0;//统计当前直线与在它之前直线的不同交点数
    for(int j=1;j<i;j++)
    {
        if(arr[j][0]==a)
        {
            if(arr[j][1]==b) return;//当加入直线与之前直线相同时,不会多出来平面
            else continue;//两直线平行无交点
        }
        else
        {
            jd[temp][0]=(b-arr[j][1])*1.0/(arr[j][0]-a);//求交点x值
            jd[temp][1]=a*1.0*jd[temp][0]+b;//求交点y值
            int flag=1;
            for(int k=0;k<temp;k++)
            {
                if(abs(jd[k][0]-jd[temp][0])<1e-6&&abs(jd[k][1]-jd[temp][1])<1e-6)//与之前交点相同,不做统计  浮点型有精度误差,判断差足够小即可
                {
                    flag=0;
                    break;
                }
            }
            if(flag==1)
            {
                temp++;
            }
        }
    }
    ans=ans+temp+1;//当前平面数=未加此直线的平面数+加入此直线时多出来的平面数   而多出来的平面数等于该直线与之前直线的不同交点数+1
}
int main()
{
    int num;
    cin>>num;
    int arr[1010][2];
    for(int i=1;i<=num;i++)
    {
        cin>>arr[i][0]>>arr[i][1];
        f(i,arr,arr[i][0],arr[i][1]);//边加入直线边计算
    }
    cout<<ans;
    return 0;
}

10.字串排序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int N = 1e5+5;
char str[N];
int main(){

	int n; 
	cin>>n;
	int r=0;
	while(r*(r+1)/2<n)r++;
	r++;

	int t=(r-1)*r/2-n;

	str[r-1]='a';
	for(int i=r-2;i>=0;i--){		
		if(t>r/2){
			str[i]=str[i+1];
			i--;
			str[i]=str[i+1];
			i--;
			t-=3;
		}else if(t>0){
			str[i]=str[i+1];
			i--;t--;
		}
		if(i>=0)str[i]=str[i+1]+1;
	}
	puts(str);
	return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值