筑梯杯郑州轻工业大学第十七届程序设计大赛(同步赛)(部分题解)
一、No idea
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
int main()
{
ll n;
cin>>n;
for(ll i=0;i<n;i++)
{
string s;
cin>>s;
for(ll j=0;j<s.size();j++)
{
if(s[j]=='2'&&s[j+1]=='0'&&s[j+2]=='2'&&s[j+3]=='4'&&j+3<s.size())
{
s[j+3]='5';
j=j+3;
}
}
cout<<s<<endl;;
}
return 0;
}
对于这一题没啥,主要就是模拟
二、超椭圆
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
double sovle(double a,double b,double n)
{
double sum=0;
double y=0;
for(double i = 0.00001; i <a; i += 0.00001)//微分成0.00001的x
{
y=b*pow(1-pow((double)i/a,n),(double)1/n);//求y
sum+=fabs(0.00001*y);//求面积,也就是求矩形面积
}
return sum*4;//由于对称,故只需要求四分之一然后再乘以四
}
signed main()
{
double a,b,n;
cin>>a>>b>>n;
double sum=sovle(a,b,n);
printf("%.6lf\n",sum);
return 0;
}
这一题利用到了数学上的微分与积分
其微分是把a分成1e5份,也就是x为0.00001,以此求y
三,小刻与奇怪队列
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
int main()
{
deque<int> s;//
ll q=0;
cin>>q;
while(q--)
{
ll x;
cin>>x;
if(x==1)
{
ll m;
cin>>m;
s.push_front(m);//进入队首
}
else if(x==2)
{
ll m;
cin>>m;
s.push_back(m);//进入队尾
}
else if(x==3)
{
ll sum=0;
if(s.size()%2==0)//判断向上取整
sum=s.size()/2;
else
sum=s.size()/2+1;
ll a[sum+1];//设立数组来存储从队列中先出来的数
ll y=0;
for(ll j=0;j<sum;j++)//直到中间位置
{
a[j]=s.front();
s.pop_front();
y++;
}
cout<<a[y-1]<<endl;//然后输出处于中间位置的数
for(ll j=y-2;j>=0;j--)
{
s.push_front(a[j]);//再逆序存入队首,同时去除中间元素
}
}
}
return 0;
}
主要利用了双端队列,deque
四,数组笑传之查查表
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define maxn 100010
struct node{
ll x;
ll y;
} s[maxn];
ll s1[maxn];
signed main()
{
ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
ll n;
cin>>n;
for(ll i=1;i<=n;i++)
{
cin>>s[i].x;
s1[i]=s[i].x;//把s数组存入s1中,为的是进行排序
}
for(ll i=1;i<=n;i++)
{
cin>>s[i].y;//输入的是代表多少个元素
}
sort(s1+1,s1+n+1);//排序为后面查找做铺垫
for(ll i=1;i<=n;i++)
{
ll x=lower_bound(s1+1,s1+n+1,s[i].x)-s1;//查找到第一个小于等于s[i].x的下标
x=x-s[i].y;//将下标向左移动y个位置
ll y=s[i].y;//将第一个下标向右移动y个位置
if(x>y)//如果是y小于x则说明二者没有交集
cout<<0<<" ";
else if(x==y)//如果相等则说明只有一个元素是二者共有的
cout<<1<<" ";
else//如果y大于x则说明有y-x+1个元素是二者共有的
cout<<y-x+1<<" ";
}
return 0;
}
五,ARK no NIGHTS
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
bool isyear(ll year)
{
return (year%4==0&&year%100!=0)||year%400==0;//判断是否·是闰年
}
ll rday(ll y,ll i)
{
ll k[13]={0,31,0,31,30,31,30,31,31,30,31,30,31};//求该月有多少天
if(i==2)return isyear(y)?29:28;//判断是否是闰二月
return k[i];//返回该月多少天
}
ll gettotol(ll y,ll m,ll d,ll h,ll m1,ll s)
{
ll sum=0;
for(ll i=1999;i<y;i++)
{
sum+=isyear(i)?366:365;//计算从1999年到本年多少天
}
for(ll i=1;i<m;i++)
{
sum+=rday(y,i);//本年的月份
}
sum+=d-1;//加上该月的已过的天数
return sum*86400+h*3600+m1*60+s;//返回一共多少秒
}
signed main()
{
ll t;
cin>>t;
while(t--)
{
ll a,b,c,d,e,f;
scanf("%lld-%lld-%lldT%lld:%lld:%lld",&a,&b,&c,&d,&e,&f);
ll a1,b1,c1,d1,e1,f1;
scanf("%lld-%lld-%lldT%lld:%lld:%lld",&a1,&b1,&c1,&d1,&e1,&f1);
ll sum=gettotol(a,b,c,d,e,f);//计算第一个日期的秒数
ll sum1=gettotol(a1,b1,c1,d1,e1,f1);//计算第二个日期的秒数
if(sum1-sum>=28800)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
signed main()
{
ll t;
cin>>t;
while(t--)
{
ll a,b,c,d,e,f;
scanf("%lld-%lld-%lldT%lld:%lld:%lld",&a,&b,&c,&d,&e,&f);
tm t1={0};
t1.tm_year=a-1900;//代表着从1900年到本年
t1.tm_mon=b-1;//从一月开始到本月
t1.tm_mday=c;//代表本月天数
t1.tm_hour=d;//小时
t1.tm_min=e;//分钟
t1.tm_sec=f;//秒
ll sum=mktime(&t1);//计算从1900年到现在多少秒
scanf("%lld-%lld-%lldT%lld:%lld:%lld",&a,&b,&c,&d,&e,&f);
t1.tm_year=a-1900;
t1.tm_mon=b-1;
t1.tm_mday=c;
t1.tm_hour=d;
t1.tm_min=e;
t1.tm_sec=f;
ll sum1=mktime(&t1);//同理也是计算总秒数
if(sum1-sum>=28800)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
对于这一题有两种方式来解决,但都是运用的相同的原理。
六,割方术
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int T;cin>>T;
while(T--)
{
int n,m,n1,m1;
cin>>n>>m>>n1>>m1;
cout<<gcd(gcd(m1,m-m1),gcd(n,n-n1))<<endl;
}
}
对于这一题要想找到最大边长,也就是寻找其最大公因数
gcd(m1, m - m1):计算宽度方向上两个关键长度的最大公约数,记为 g_1。这个最大公约数 g_1 是能同时整除 m1 和 (m - m1) 的最大整数,意味着边长为 g_1 的正方形可以在宽度方向上无剩余地填充。
gcd(n, n - n1):计算长度方向上两个关键长度的最大公约数,记为 g_2。同样,边长为 g_2 的正方形可以在长度方向上无剩余地填充
gcd(g_1, g_2):最后再计算 g_1 和 g_2 的最大公约数。这个最终结果就是能同时满足在长度和宽度方向上无剩余填充 “L” 形的最大正方形边长 k。
总结
通过补题才发现有太多没了解过的东西,像mktime函数,以及求最大公因数的函数gcd。