括号( brackets )
【问题描述】
牛牛有一个字符串,这个字符串是由左括号 ( 和右括号 ) 组成的。这样的字符串
又叫做括号序列。
牛牛想知道,他的括号序列是不是一个回文括号序列。与一般的回文串不同,牛牛
的回文括号序列定义为“看上去”是回文的括号序列。例如牛牛认为,)()(是回文括号序列,而 )(()不.是 回文括号序列。形式化地说,一个长度为 k 的括号序列是回文的,当且仅当对于所有的 i(1 ≤ i ≤ k)从左向右数的第 i 个字符和从右向左数的第 i 个字符是相反的。
【输入格式】
从文件 brackets.in 中读入数据。
第一行包含一个正整数 T(1 ≤ T ≤ 100) ,表示这个测试点内的数据组数。
接下来 T 行,每行一个长度不超过 100 的字符串,表示牛牛的括号序列。
【输出格式】
输出到文件 brackets.out 中。
输出 T 行,依次表示 T 组数据的答案,如果这个括号序列是回文括号序列,那么
这一行输出 Yes ,否则输出 No 。
【样例输入】
2
())(
(())
【样例输出】
No
Yes
送分题,判断回文数
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int read() { int f=1,ans=0;char c; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } char str[1001]; int t; int main() { freopen("brackets.in","r",stdin); freopen("brackets.out","w",stdout); t=read(); while(t--){ scanf("%s",str+1); bool ff=true; int len=strlen(str+1); if(len%2==1){ cout<<"No"<<endl; continue; } for(int i=1;i<=len/2;i++){ if(str[i]==str[len-i+1]){ ff=false; break; } } if(ff){cout<<"Yes"<<endl;} else cout<<"No"<<endl; } }
地球危机( attack )
【题目描述】
三体人将对地球发起攻击。为了抵御攻击,地球人派出了 A × B ×C 艘战舰,在太
空中排成一个 A 层 B 行 C 列的立方体。其中,第 i 层第 j 行第 k 列的战舰(记为战舰
(i, j,k))的生命值为 d i,j,k 。三体人将会对地球发起 m 轮“立方体攻击”,每次攻击会对一个小立方体中的所有战舰都造成相同的伤害。具体地,第 t 轮攻击用 7 个参数 la t ,ra t ,lb t ,rb t ,lc t ,rc t ,h t 描述;所有满足 i ∈ [la t ,ra t ], j ∈ [lb t ,rb t ],k ∈ [lc t ,rc t ] 的战舰 (i, j,k) 会受到 h t 的伤害。如果一个战舰累计受到的总伤.害超过其生命值,那么这个战舰会爆炸。地球指挥官希望你能告诉他,第一艘爆炸的战舰是在.哪.一.轮攻击后爆炸的。
【输入格式】
从文件 attack.in 中读入数据。
第一行包括 4 个正整数 A, B,C,m;
第二行包含 A × B ×C 个整数,其中第 ((i − 1) × B + (j − 1)) ×C + (k − 1) + 1 个数
为 d i,j,k ;
第 3 到第 m + 2 行中,第 (t − 2) 行包含 7 个正整数 la t ,ra t ,lb t ,rb t ,lc t ,rc t ,h t 。
【输出格式】
输出到文件 attack.out 中。
输出第一个爆炸的战舰是在哪一轮攻击后爆炸的。保证一定存在这样的战舰。
【样例 1 输入】
2 2 2 3
1 1 1 1 1 1 1 1
1 2 1 2 1 1 1
1 1 1 2 1 2 1
1 1 1 1 1 1 2
【样例 1 输出】
2
【样例 1 解释】
在第 2 轮攻击后,战舰 (1,1,1) 总共受到了 2 点伤害,超出其防御力导致爆炸。
第 3 页 共 6 页
【子任务】
对于 10% 的数据,B = C = 1;
对于 20% 的数据,C = 1;
对于 40% 的数据,A × B ×C,m ≤ 10,000;
对于 70% 的数据,A, B,C ≤ 200;
对于所有数据,A × B ×C ≤ 10 6 ,m ≤ 10 6 ,0 ≤ d i,j,k ,a t ≤ 10 9 。
说一说思想,代码就是别人的了,因为实在不想写了
大家如果做了借教室就发现这是一个加了两维的升级版
所以还是差分+二分
一维差分后不是扫一次
二维扫两次(横,竖)
三维扫三次,(横,竖,高)
然后就瞎搞了
其实可以二分,可以吧m优化成logm
时间复杂度:O(logm(ABC+M))
然后再可以通过mid的移动不用每次重新更新差分数组
所以加加减减
还可以将复杂度转换成:O(logm(ABC)+M)
好像还有一个玄学优化,却忘了
#include<algorithm> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<iomanip> #include<iostream> #include<map> #include<queue> #include<stack> #include<vector> #define rep(i,x,y) for(register int i=(x);i<=(y);i++) #define dwn(i,x,y) for(register int i=(x);i>=(y);i--) #define maxn 1000010 #define LL long long using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)&&ch!='-')ch=getchar(); if(ch=='-')f=-1,ch=getchar(); while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); return x*f; } void write(int x) { int f=0;char ch[20]; if(!x){putchar('0'),putchar(' ');return;} if(x<0)x=-x,putchar('-'); while(x)ch[++f]=x%10+'0',x/=10; while(f)putchar(ch[f--]); putchar(' '); } LL qh[maxn],a[maxn],s[maxn],d[maxn]; int qxa[maxn],qya[maxn],qza[maxn],qxb[maxn],qyb[maxn],qzb[maxn],A,B,C,m,ans; int getx(int x,int y,int z){return (x*B+y)*C+z+1;} void getp(int x,int px,int py,int pz){x--;pz=x%C,x/=C,py=x%B,pz=x/B;return;} void add(int x,int y,int z,LL h){if(x<=(A-1)&&y<=(B-1)&&z<=(C-1))a[getx(x,y,z)]+=h;} void atk(int xa,int ya,int za,int xb,int yb,int zb,LL h) { add(xa,ya,za,h),add(xa,ya,zb+1,-h),add(xa,yb+1,za,-h),add(xa,yb+1,zb+1,h); add(xb+1,ya,za,-h),add(xb+1,ya,zb+1,h),add(xb+1,yb+1,za,h),add(xb+1,yb+1,zb+1,-h); } int check() { rep(i,0,A-1)rep(j,0,B-1)rep(k,0,C-1)s[getx(i,j,k)]=a[getx(i,j,k)]; if(C!=1)rep(i,0,A-1)rep(j,0,B-1)rep(k,1,C-1)s[getx(i,j,k)]+=s[getx(i,j,k-1)];//,cout<<i<<" "<<j<<" "<<k<<"+1 "<<s[getx(i,j,k-1)]<<endl; if(B!=1)rep(i,0,A-1)rep(j,1,B-1)rep(k,0,C-1)s[getx(i,j,k)]+=s[getx(i,j-1,k)];//,cout<<i<<" "<<j<<" "<<k<<"+2 "<<s[getx(i,j-1,k)]<<endl; if(A!=1)rep(i,1,A-1)rep(j,0,B-1)rep(k,0,C-1)s[getx(i,j,k)]+=s[getx(i-1,j,k)];//,cout<<<<"+3 "<<s[getx(i-1,j,k)]<<endl; rep(i,0,A-1)rep(j,0,B-1)rep(k,0,C-1)if(s[getx(i,j,k)]>d[getx(i,j,k)])return 1; return 0; } void getans(int L,int R,int lastmid) { if(L>R)return; int mid=(L+R)>>1; if(mid>lastmid)rep(i,lastmid+1,mid)/*cout<<"mid:"<<mid<<" add:"<<i<<endl,*/atk(qxa[i],qya[i],qza[i],qxb[i],qyb[i],qzb[i],qh[i]); if(mid<lastmid)rep(i,mid+1,lastmid)/*cout<<"mid:"<<mid<<" del:"<<i<<endl,*/atk(qxa[i],qya[i],qza[i],qxb[i],qyb[i],qzb[i],-qh[i]); int f=check(); //cout<<"mid:"<<mid; //cout<<"now:"; //rep(i,0,A-1)rep(j,0,B-1)rep(k,0,C-1)cout<<s[getx(i,j,k)]<<" ";cout<<endl; if(f){ans=min(ans,mid);getans(L,mid-1,mid);} else getans(mid+1,R,mid); } int main() { freopen("attack.in","r",stdin); freopen("attack.out","w",stdout); A=read(),B=read(),C=read(),ans=m=read(); rep(i,0,A-1)rep(j,0,B-1)rep(k,0,C-1)d[getx(i,j,k)]=read(); rep(i,1,m)qxa[i]=read()-1,qxb[i]=read()-1,qya[i]=read()-1,qyb[i]=read()-1,qza[i]=read()-1,qzb[i]=read()-1,qh[i]=read(); getans(1,m,0); write(ans); return 0; } /* 2 2 2 3 1 1 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 1 2 */
付账( eatout )
【题目描述】
几个人一起出去吃饭是常有的事。但在结帐的时候,常常会出现一些争执。
现在有 n 个人出去吃饭,他们总共消费了 S 元。其中第 i 个人带了 a i 元。幸运的
是,所有人带的钱的总数是足够付账的,但现在问题来了:每个人分别要出多少钱呢?
为了公平起见,我们希望在总付钱量恰好为 S 的前提下,最后每个人付的钱的标
准差最小。这里我们约定,每个人支付的钱数可以是任意非负实数,即可以不是 1分钱的整数倍。你需要输出最小的标准差是多少。标准差的介绍:标准差是多个数与它们平均数差值的平方平均数,一般用于刻画这些数之间的“偏差有多大”。形式化地说,设第 i 个人付的钱为 b i 元,那么标准差为
【输入格式】
从文件 eatout.in 中读入数据。
第一行包含两个整数 n、S;
第二行包含 n 个非负整数 a 1 ,...,a n 。
【输出格式】
输出到文件 eatout.out 中。
输出最小的标准差,四舍五入保留 4 位小数。保证正确答案在加上或减去 10 −9 后
不会导致四舍五入的结果发生变化。
【样例 1 输入】
5 2333
666 666 666 666 666
【样例 1 输出】
0.0000
【样例 1 解释】
每个人都出
2333/5元,标准差为 0。
【样例 2 输入】
10 30
2 1 4 7 4 8 3 6 4 7
【样例 2 输出】
0.7928
【子任务】
对于 10% 的数据,所有 a i 相等;
对于 30% 的数据,所有非 0 的 a i 相等;
对于 60% 的数据,n ≤ 1,000;
对于 80% 的数据,n ≤ 10 5 ;
对于所有数据,n ≤ 5 × 10 5 ,0 ≤ a i ≤ 10 9 。
把式子推一推,然后简单贪心就可以
注意精度
#include<algorithm> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<iomanip> #include<iostream> #include<map> #include<queue> #include<stack> #include<vector> using namespace std; inline long long read() { long long f=1,ans=0;char c; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } long long n,s; long long x[500001]; long double ans,avg,avg1,ss; int main() { // freopen("eatout.in","r",stdin); // freopen("eatout.out","w",stdout); n=read(),s=read(); avg=s/n,avg1=avg,ss=s; for(long long i=1;i<=n;i++) x[i]=read(); sort(x+1,x+n+1); for(long long i=1;i<=n;i++) { if(x[i]<=avg1) ans+=(avg-x[i])*(avg-x[i]),ss=ss-x[i],avg1=ss/(n-i); else if(x[i]>avg1)ans+=(avg-avg1)*(avg-avg1),ss=ss-avg1; } cout<<fixed<<setprecision(4)<<sqrt(ans/n); return 0; } /* 10 30 2 1 4 7 4 8 3 6 4 7 */