持续更新~~直到省赛
#8 The 14-th BIT Campus Programming Contest()GYM
A - 两只脑斧
# include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
string a;
char f[10]={'X','E','I','E','I','E','I','I'};
scanf("%d",&n);
getchar();
for(int i=0;i<n;i++){
cin>>a;
getchar();
printf("%c",f[a[0]-'0']);
}
return 0;
}
K - 多项式求导
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a[120];
const LL mod=998244353;
int main()
{
LL n,k;
scanf("%lld %lld",&n,&k);
for(LL i=n;i>=0;i--){
scanf("%lld",&a[i]);
}
for(LL i=0;i<k;i++){
printf("0 ");
}
for(LL i=n;i>=0;i--){
if(i>=k){
for(LL j=i;j>(i-k);j--){
a[i]=((a[i]%mod)*(j%mod))%mod;
}
a[i]=a[i]%mod;
printf("%lld ",a[i]);
}else{
break;
}
}
return 0;
}
F - 风王之瞳
我太傻逼了,居然以为算一类边长要分别对长和宽做组合数,。。。,然而是不用的,阔以直接算出来的。
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
int t;
scanf("%d",&t);
while(t--){
LL n,m;
LL sum=0;
scanf("%lld %lld",&n,&m);
LL end=min(n,m);
for(LL i=1;i<=end;i++){
if(i==1){
sum+=(n*m);
//cout<<sum<<endl;
}else{
LL dn=(n-(i-1));
LL dm=(m-(i-1));
sum+=(dn*dm*i);
//cout<<sum<<endl;
}
}
printf("%lld\n",sum);
}
return 0;
}
H - 目标是成为数论大师
其实就是解方程组,但是有一个坑点就是要注意增根的情况,把他去掉
# include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--){
int a,b;
scanf("%d %d",&a,&b);
int g=4*a*b+a*a;
if(g<0){
}else if(g==0){
printf("1\n");
printf("%d\n",(2*b+a)/2);
}else if(g>0){
int flag1=0,flag2=0;
int x=((2*b+a)-sqrt(g))/2;
int y=((2*b+a)+sqrt(g))/2;
if((sqrt(a*x)+b)==x){
flag1=1;
}
if((sqrt(a*y)+b)==y){
flag2=1;
}
if(flag1&&flag2){
printf("2\n");
printf("%d %d\n",x,y);
}else{
printf("1\n");
if(flag1){
printf("%d\n",x);
}else{
printf("%d\n",y);
}
}
}
}
return 0;
}
C - 赛尔逵传说
c老师教的:(蟹蟹萌萌的c老师)x次打死一只小怪兽,收到x-1次伤害,使用一个道具相当于增加一次攻击,也就少了一次伤害。然后把这些抵消伤害的机会用在攻击高的小怪兽上。按照血量可以算出,每个小怪兽攻击几次,选择最大的c个,尽量让多出来的一次攻击减少最多的伤害。
血的教训,开 long long要开得彻底。。。
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MAXN=1e5+10;
pair<LL,LL> p[MAXN];
int main()
{
LL n,k,c;
scanf("%lld %lld %lld",&n,&k,&c);
for(LL i=0;i<n;i++){
scanf("%lld %lld",&p[i].second,&p[i].first);
}
sort(p,p+n,greater<pair<LL,LL> >());
// for(int i=0;i<n;i++){
// cout<<i<<" "<<p[i].first<<" "<<p[i].second<<endl;
// }
//p[i].second是血量,p[i].first是攻击值
LL l;
for(LL i=0;i<n;i++){
LL d=p[i].second/k-1;//d为需要的果子数
if(p[i].second%k!=0){
d++;
}
if((c-d)<=0){
p[i].second-=(c*k);
l=i;
if((c-d)==0) l++;
break;
}else{
c-=d;
}
}
//cout<<l<<endl;
LL sum=0;
for(LL i=l;i<n;i++){
LL ans=p[i].second/k;//ans为收到的攻击次数
if(p[i].second%k==0){
ans--;
}
sum+=(ans*p[i].first);
}
printf("%lld",sum);
return 0;
}
ZZUACM快乐集训#3 (SamaraSAUACMICPCQuarternalQualicationContestRussia,Samara,Septemb er22,2012)
L - Hard Problem
签到题(不要交错题。。。血的教训)
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MAXN=2e5+20;
LL x[MAXN];
int main()
{
LL n;
scanf("%lld",&n);
scanf("%lld",&x[0]);
printf("%lld",x[0]);
for(int i=1;i<n;i++){
printf(" ");
scanf("%lld",&x[i]);
printf("%lld",x[i]-x[i-1]);
}
return 0;
}
K - Bracket Sequence
l类似括号匹配,用栈来写就可以,但要注意一点就是。stack.pop()之前要判断stack.empty()
# include<bits/stdc++.h>
using namespace std;
stack<char> a;
int main()
{
string b;
string s;
cin>>b;
for(int i=0;i<b.length();i++){
if(!a.empty()&&a.top()==')'){
printf("IMPOSSIBLE");
return 0;
}
// if(!a.empty())
// cout<<i<<" "<<a.top()<<endl;
if(b[i]==')'){
if(!a.empty()&&a.top()=='('){
a.pop();
}else{
a.push(b[i]);
}
}else{
a.push(b[i]);
}
}
if(!a.empty()&&a.top()==')'){
printf("IMPOSSIBLE");
return 0;
}else{
cout<<b;
if(a.empty()){
}else{
for(int j=0;j<a.size();j++){
printf(")");
}
}
}
return 0;
}
G - The Last Wish
s算是个简单题,但是看到简单题不要太开心,题目要看清楚(QAQ)是要改变次数最少
# include <bits/stdc++.h>
using namespace std;
int f[30];
int main()
{
string s;
cin>>s;
int d=0;
if(s.length()>26){
printf("IMPOSSIBLE");
}else{
for(int i=0;i<s.length();i++){
f[s[i]-'a']=2;
}
for(int i=0;i<s.length();i++){
if(f[s[i]-'a']==2){
f[s[i]-'a']=1;
printf("%c",s[i]);
}else{
while(d<26){
if(f[d]==1||f[d]==2){
d++;
}else{
f[d]=1;
printf("%c",char(d+97));
break;
}
}
}
}
}
return 0;
}
E - Counterfeiters
就是算一个概率题,题目没读懂也是没谁了,大意就是有两枚硬币,然后分别选中第一枚或者第二枚,在第一次扔到头朝上的情况下,算出第二次扔到头朝上的概率(两次扔的是同一枚硬币),就是一个条件概率
# include <bits/stdc++.h>
using namespace std;
int main()
{
int p,q;
double pp;
scanf("%d %d",&p,&q);
pp=(p*p*1.0+q*q*1.0)/(p*1.0+q*1.0);
printf("%.15f",pp/100.0);
return 0;
}
D - Insomnia
递归就可以,但是要把递归过的数字存起来,不然会T;
# include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
int f[MAXN];
bool Is_prime(int n)
{
if(n==1) return false;
if(n==2||n==3) return true;
if(n%6!=1&&n%6!=5) return false;
for(register int i=5;i*i<=n;i+=6)
if(n%i==0||n%(i+2)==0)
return false;
return true;
}
int digui(int nn)
{
int s=1;
if(Is_prime(nn)){
//cout<<"@"<<s<<endl;
return s;
}else{
for(int i=2;i<nn;i++){
if(nn%i==0){
if(f[i]==0){
f[i]=digui(i);
}
s+=f[i];
}
}
}
return s;
}
int main()
{
int k;
int sum=1;
scanf("%d",&k);
for(int i=2;i<k;i++){
if(k%i==0){
//cout<<sum<<endl;
if(f[i]==0){
f[i]=digui(i);
}
sum+=f[i];
// cout<<digui(i)<<endl;
}
}
printf("%d",sum);
return 0;
}
M - Jumping along the Hummocks
学长们说是用DP做的,由于本人太菜了,还不会DP,就用了一种别的方法做,不知道是不是DP
就是任取一点,求出起始点到这个点的最短步数和这个点到终点的最短步数,那么这两个加起来就是起始点经过这个点的步数,遍历一遍所有点,求出最小的就可以,有一种从中间的感觉
# include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+20;
int c[MAXN];
int f[MAXN];
int b[MAXN];
int ff[MAXN];
int e[MAXN];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
}
f[c[1]]=1;
for(int i=2;i<=n;i++){
if(f[c[i]]){
b[i]=min(b[i-1],b[f[c[i]]])+1;
}else{
b[i]=b[i-1]+1;
}
f[c[i]]=i;
}
// for(int i=1;i<=n;i++){
// cout<<b[i]<<endl;
// }
// cout<<endl<<"@"<<endl;
ff[c[n]]=n;
for(int i=n-1;i>=1;i--){
if(ff[c[i]]){
e[i]=min(e[i+1],e[ff[c[i]]])+1;
}else{
e[i]=e[i+1]+1;
}
ff[c[i]]=i;
}
// for(int i=1;i<=n;i++){
// cout<<e[i]<<endl;
// }
// cout<<endl<<"@"<<endl;
int minn=MAXN;
for(int i=1;i<=n;i++){
int a=b[i]+e[i];
if(a<minn) minn=a;
}
cout<<minn;
return 0;
}