第二届中国计量大学ACM程序设计竞赛个人赛(同步赛)
A Little Gyro and Sort
快读加快排
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int a[10005];
int main(void)
{
int t;scanf("%d",&t);
while(t--){
int n;scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
for(int i=0;i<n-1;i++){
printf("%d ",a[i]);
}
printf("%d\n",a[n-1]);
}
return 0;
}
B Little Gyro and Sets
不是m的倍数总和 减去 是m的倍数 的和
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int main(void)
{
int t;cin>>t;
while(t--){
ll a,b;cin>>a>>b;
ll c=b/a;//A=(1+c)*c/2*a
cout<<(1+b)*b/2-(1+c)*c*a<<endl;
}
return 0;
}
C Little Gyro and Numbers
p^q 和 q^p的比较,曾经一道比较难思考的高考题
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int read()
{
int c=0;
char s;
while((s=getchar())>'9'||s<'0');
c=s-'0';
while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
return c;
}
int a[100005],b[100005];//a用来按顺序输出的,b用来排序
int main(void)
{
int m;m=read();
for(int k=1;k<=m;k++){
int n;cin>>n;
for(int i=0;i<n;i++){
a[i]=read();
//以下处理使3的数排列后变成了首位
if(a[i]==2)//为什么?当p为2时,只有q大于4时才能情况++
a[i]=4;//而b中的2变成了4没有影响
//巧妙的是,3^2>2^3,所以,2变成4是很巧妙的
if(a[i]==1)//1和任何的数相比都不能情况++,所有放在最后了
a[i]=inf;
b[i]=a[i];
}
sort(b,b+n);
cout<<"Case "<<k<<":"<<endl;
for(int i=0;i<n;i++)//找到第一个比a【i】大的数,并返回下标。
printf("%d\n",n-(upper_bound(b,b+n,a[i])-b));
}
return 0;
}
D Little Gyro and Array
用树状数组维护差分数组可以过
搞了我一天多,一个渣渣学了好多东西。
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
typedef long long ll;
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
ll read()
{
ll c=0;int flag=1;
char s;
while((s=getchar())>'9'||s<'0')if(s=='-')flag=-1;
c=s-'0';
while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
return c*flag;
}
ll n,m;
ll a[100005];
ll t1[100005];
ll t2[100005];
void add(int L, int R, ll x, ll y)
{
for(int i=L;i<=n;i+=i&-i){t1[i]+=x; t2[i]+=y;}
for(int i=R+1;i<=n;i+=i&-i){t1[i]-=x; t2[i]-=y;}
}
ll ask(int p)
{
ll x=0, y=0;
for(int i=p;i;i-=i&-i){x+=t1[i]; y+=t2[i];}
return x + p*y;
}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
while(m--){
int q;cin>>q;
if(q==1){
int l,r,k,d;cin>>l>>r>>k>>d;
//b[l]+=k;b[r+1]-=k+(r-l)*d; 即区间(l+1,r)值加(r-l)*d
add(l,r,k-d*l,d);
}
else{
int q;cin>>q;
cout<<a[q]+ask(q)<<endl;
}
}
return 0;
}
E Little Gyro and Derrick
得走到哪就拦到哪,边角是主要点
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int read()
{
int c=0;int flag=1;
char s;
while((s=getchar())>'9'||s<'0')if(c=='-')flag=-1;
c=s-'0';
while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
return c*flag;
}
int main(void)
{
int t;cin>>t;
while(t--){
int n,m,k;cin>>n>>m>>k;
int temp=0;
while(k--){
int x,y;cin>>x>>y;
if(x<=5||x>=n-4||y<=5||y>=m-4)temp=1;
//为什么是5,自己模拟一下就可以得出至少把它封4步
//如果大于5,就先把4个角各先封了一边
}
if(temp) cout<<"Happy Little Gyro\n";
else cout<<"Sad Little Gyro\n";
}
return 0;
}
F Little Gyro and Sequences
问题问得很巧妙,第一问是最大上升不能等值的
而第二问是可以转化为为问最大下降能等值,具体搞几个实例就可以模拟一下了
这里用了O(nlogn)的算法。
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int a[200005];
int b[200005];
int read()
{
int c=0;
char s;
while((s=getchar())>'9'||s<'0');
c=s-'0';
while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
return c;
}
int main(void)
{
int n;cin>>n;
for(int i=0;i<n;i++){
a[i]=read();
}
int len=0;//新数组的长度
b[0]=a[0];
for(int i=1;i<n;i++){
if(b[len]<a[i]){
len++;
b[len]=a[i];
}
else{
//二分查找,将从左到右边数第 1 个大于 'temp' 的数字更新为 6
int l=0,r=len;
int temp=a[i];
while(l<r){
int mid=(l+r)/2;
if(b[mid]<temp) l=mid+1;
else r=mid;
}
b[r]=temp;
}
}
int up=len;
memset(b,0,sizeof b);
len=0;
b[0]=a[0];
for(int i=1;i<n;i++){
if(b[len]>=a[i]){
len++;
b[len]=a[i];
}
else{
//二分查找
int l=0,r=len;
int temp=a[i];
while(l<r){
int mid=(l+r)/2;
if(b[mid]>=temp) l=mid+1;
else r=mid;
}
b[r]=temp;
}
}
cout<<up+1<<" "<<len+1;
return 0;
}
G Disk Scheduling
不是要求你想的那个最优算法,而是按着它给你的方法求,就是指针头要往最小的那个方向来回跑。
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int a[1000005];
int read()
{
int c=0;
char s;
while((s=getchar())>'9'||s<'0');
c=s-'0';
while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
return c;
}
int main(void)
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
a[i]=read();
}
sort(a+1,a+1+n);
//for(int i=1;i<=n;i++)cout<<a[i]<<" ";
int l=1,r=n;//指针
for(int i=1;i<n;i++){
if(a[i]<=m&&a[i+1]>=m){
l=r=i;break;
}
}
r++;//走一步
ll num=0;
while(l>0||r<=n){
//cout<<l<<" "<<r<<endl;
if((r!=n+1&&a[r]-m<m-a[l])||l==0){
num+=a[r]-m;
m=a[r];
r++;
}
else{
num+=m-a[l];
m=a[l];
l--;
}
}
cout<<num;
return 0;
}
H Monster Fighting
打怪要耗血,但是打完可以补血
根据这只怪是可以补血还是耗血先给分类,然后把可以补的重小到大先补了,再把耗血的重大到小打了,一有不行的就不行了。
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int read()
{
int c=0;int flag=1;
char s;
while((s=getchar())>'9'||s<'0')if(s=='-')flag=-1;
c=s-'0';
while((s=getchar())<='9'&&s>='0') c=c*10+s-'0';
return c*flag;
}
struct node
{
int l,r;
}a[100005],b[100005];
bool cmp(node aa,node bb)
{
return aa.l<bb.l;
}
int main(void)
{
int t;t=read();
while(t--){
ll n,m;n=read(),m=read();
int a1=0,a2=0;
int x,y;
for(int i=1;i<=n;i++){
x=read(),y=read();
if(x<=y) a[++a1].l=x,a[a1].r=y-x;
else b[++a2].l=x,b[a2].r=y-x;
}
sort(a+1,a+1+a1,cmp);
sort(b+1,b+1+a2,cmp);
int temp=1;
for(int i=1;i<=a1;i++)//把可以补血的给先吃了
if(m>a[i].l) m+=a[i].r;
else{temp=0;break;}
for(int i=a2;i>=1;i--){//先打耗血最多的
if(m>b[i].l) m+=b[i].r;
else{temp=0;break;}
}
printf(temp?"Yes\n":"No\n");
}
return 0;
}
I Logs Stacking
很神奇的一道题,最后变成了求斐波那契数列的后4位,而后4为在15000这里是一个循环点,要验证的话跑一遍就知道了
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int a[15005];
int main(void)
{
a[1]=1;
for(int i=2;i<=15001;i++){
a[i]=a[i-1]+a[i-2];
a[i]%=10000;
}
int t;cin>>t;
while(t--){
int k;cin>>k;
cout<<a[k%15000]<<endl;
}
return 0;
}
L Story of Eden
刚开始被英语吓到了
#include<bits/stdc++.h>
#define MAX_INT ((unsigned)(-1)>>1)
#define MIN_INT (~MAX_INT)
#define pi 3.1415926535898
#define ll long long
#define inf 0x3f3f3f3f
#define infmax 0x3f3f3f3f3f3f3f3f
using namespace std;
int main(void)
{
int t;cin>>t;
while(t--){
string s;
cin>>s;
cout<<"Love replied to "<<s<<", \"Nothing is good or bad, and the interpretation is in people.\""<<endl;
}
return 0;
}