A:
int offset[4][2] = { (1, 0), (0, 1), (-1, 0), (0, -1) };
int offset[4][2] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
2.若E 1,E 2,...,E n都是合法的运算式,则E 1,E 2,...,E n也是个合法的运算式,并且其值为E n的值。
3.若E是个合法的运算式,则(E)也是个合法的运算式,其值为E的值。
无法用上列1,2,3项的关系推出的运算式,都是不合法的。
举例来说514,1,2,(-2147483648,2,4),(((0))),(1),(2)都是此题中合法的运算式,但0514,-02,(),(23,43))都是不合法的。
输入描述:
输入仅有一行,包含一个字串e,是一个仅由左右小括号'(',')',逗号',',以及整数所组成的合法运算式。
输出描述:
输出一行包含一个整数,代表输入所提供的运算式的运算结果
输入
(5,-14)
输出
-14
备注:
1≤|e|≤100 e中所有整数的范围为-231≤ x ≤231-1
题目分析:简单分析可以知道,答案就是最后一个出现的数字
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin>>str;
int sum=0,flag=0;
for (int i=0;i<str.size();i++) {
if (str[i]=='('||str[i]==',') {
flag=sum=0;
}
else if (str[i]>='0'&&str[i]<='9'||str[i]=='-'){
if (str[i]=='-') flag=1;
else sum=sum*10+str[i]-'0';
}
}
cout<<(flag?(sum*-1):sum)<<endl;
return 0;
}
B:
沃老师并不会告诉大家分数的排名,但学生间竞争激烈,大家都想知道自己的作文成绩在班上的排名。Amy 8.999999999999999999999999999999999999999990000
Bob 8.9999999999999999999999999999999999999999800
Cat 8.9999999999999999999999999999999999999999899999999
输入描述:
输入共有N + 1行。 第一行有一个正整数N,代表班上有几个人。 接下来N行中的第i行,包含一个字符串namei,以及一个小数scorei,分别代表第i个人的名字以及第i个人的作文得分。
输出描述:
输出总共N行,每行由一个名字和一个小数构成,第i行代表着分数第i高的人的名字以及他的作文得分,代表作文得分的小数必须和输入一模一样,也就是原本末尾有多少零,输出也要有相同数量的零。 若分数相同,则名字字典序比较小的放在前面。
输入
3 Amy 8.999999999999999999999999999999999999999990000 Bob 8.9999999999999999999999999999999999999999800 Cat 8.9999999999999999999999999999999999999999899999999
输出
Amy 8.999999999999999999999999999999999999999990000 Cat 8.9999999999999999999999999999999999999999899999999 Bob 8.9999999999999999999999999999999999999999800
备注:
2≤N≤2×105 1≤字串名称的长度≤11 namei由数字及大小写英文字母组成 若i≠j,则namei≠namej 所有名称的长度总和≤6×105 scorei包含三个部分:整数部分,小数点,小数部分 整数部分一定恰只有一个字元(数字'0'〜'9'之一) 一定有小数点('.') 小数部分由'0'〜'9'组成,长度可为0,也可以由字元'0'结尾 若把scorei视为字符串,所有scorei的长度总和≤6×105
题目分析:我们把成绩的末尾0去掉后保存到另一个string里面,然后可以直接根据字符串比较大小。
感觉这里面有一个坑,cmp函数如果你的参数不加引用就T了。
感觉合理的解释是:因为cmp函数被多次调用,不加引用,那么每一次都需要开一个空间,把实参传给形参,赋值过程很耗时。加了引用,就不需要重新赋值过程。
如有错,欢迎评论区给出正确解释,谢谢。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2*1e5+100;
struct note{
string name,score,pre;
}person[maxn];
void solve(string &s)
{
int first=0;
int len=s.size();
for (int i=len-1;i>=0;i--) {
if (s[i]=='0') first++;
else break;
}
if (first<len) s=s.substr(0,len-first);
}
bool cmp(note &a,note &b)
{
if (a.score==b.score) {
return a.name<b.name;
}
return a.score>b.score;
}
int main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++) {
cin>>person[i].name>>person[i].score;
person[i].pre=person[i].score;
solve(person[i].score);
}
sort(person+1,person+1+n,cmp);
for (int i=1;i<=n;i++) {
cout<<person[i].name<<" "<<person[i].pre<<endl;
}
return 0;
}
C
吉姆是个热爱算法竞赛的小朋友,平常的休闲活动就是刷 牛客网 的题目。
当吉姆刷到 wannafly挑战赛12 F.小H和圣诞树 这题时,颇为震惊,因为这是他第一次在wannafly挑战赛上看到作者提供的解答的时间复杂度的式子里含有根号的题目,于是吉姆就开始在网络上搜寻拥有类似时间复杂度解法的问题,并且看到了以下这题:
给你一个有 N 个点 M 条边的无向简单图,请算算此图中有几个三角形。我们称无序的三个点 x,y,z 为三角形,若且唯若 (x,y)、(y,z)、(x,z) 都是此图上的边。吉姆 想了这个问题七天七夜后,他发现了一件事情:
(1) 对于任一个度数为 d 的点,我们可以用 O(d 2) 的时间复杂度来计算有多少三角形包含这该点。
吉姆 又想了这个问题七天七夜后,他又发现了一件事情:
(2) 对于任一个点,我们可以用 O(M) 的时间复杂度来计算有多少三角形包含该点。
吉姆又再想了这个问题十四天十四夜后,他忽然想到:
(3) 不如就把 (1) 和 (2) 的算法结合在一起!找一个恰当的整数s 若一个点度数小于等于s,就使用(1),否则就使用(2),经过缜密的时间复杂度分析,发现这么做的时间复杂度会是 ,取 ,时间复杂度就会是 。最后再把包含各个点的三角形数全部加起来再除以 3 就是答案了! (因为每个三角形会被算到三次。) (此时间复杂度的详细证明会在今天的题解中解说唷~)
但这个 s 的值究竟要设为多少呢?这就和 (1) 与 (2) 两种方法的执行时间的常系数有关了。
于是,吉姆为了透彻了解这个问题,就假定(1) 和(2) 的常系数分别是a 与b,这意思是:对于一个度数为d 的点,若使用(1),程式的执行时间和a×d 2 成正比;若使用(2),程式的执行时间则和b×M 成正比。
对于一个给定的图,吉姆想要知道对于不同的 a,b,s 的值要取多少比较好,并且求出 s 为该值时程式所需的执行时间!
(deg i 和 freq i 对应到 Background 里提到的问题的意思就是:度数为 deg i 的点 有 freq i 个。)
你要回答 Q 个问题,第 i 个问题会给你 2 个正整数 a i, b i,请找到一个整数 s 使得以下式子(E i) 的值最小:
(此式就是 Background 里提到的程式执行时间的估计函数)
输入描述:
输入共有 1+L+1+Q 行。 第一行有有两个正整数 M,L。 接下来的 L 行中的第 i 行有两个正整数 degi 和 freqi。 下一行有一个正整数 Q。 最后 Q 行中的第 i 行有两个正整数 ai, bi。
输出描述:
对于每个询问都输出一行包含一个整数,代表式子 Ei 的最小值。题目分析:题目很长,很烦。简单就是确定最优的s使得E最小。
三分来求最优解,结果还需要对俩个极端情况(全是a,全是b)进行比较就好了。
因为是多组查询,我们需要进行一下预处理。
题目说的数据不超过long long,那是表示结果不超过,计算过程中就超过了。
还有更简单的做法!!!
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
final static int maxn=(int) (2*1e5+100);
static BigInteger deg []= new BigInteger[maxn];
static BigInteger freg []= new BigInteger[maxn];
static BigInteger sum_a []= new BigInteger[maxn];
static BigInteger sum_b []= new BigInteger[maxn];
static int a,b;
public static BigInteger f (int pos) {
BigInteger A=sum_a[pos].multiply(BigInteger.valueOf(a));
BigInteger B=sum_b[pos+1].multiply(BigInteger.valueOf(b));
return A.add(B);
}
public static BigInteger min(BigInteger a,BigInteger b) {
if (a.compareTo(b)>0) return b;
else return a;
}
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
BigInteger M=cin.nextBigInteger();
int L=cin.nextInt();
for (int i=1;i<=L;i++) {
deg[i]=cin.nextBigInteger();
freg[i]=cin.nextBigInteger();
}
sum_a[0]=sum_b[L+1]=BigInteger.valueOf(0);
for (int i=1;i<=L;i++) {
sum_a[i]=sum_a[i-1].add(deg[i].multiply(deg[i].multiply(freg[i])));
}
for (int i=L;i>=1;i--) {
sum_b[i]=sum_b[i+1].add(freg[i].multiply(M));
}
int Q=cin.nextInt();
while ((Q--)>0) {
a=cin.nextInt();
b=cin.nextInt();
int left=0,right=L;
while (right-left>1) {
int mid=(right+left)/2;
int mmid=(mid+right)/2;
if (f(mid).compareTo(f(mmid))>0) left=mid;
else right=mmid;
}
BigInteger ans=min(f(left),f(right));
BigInteger res=min(sum_a[L].multiply(BigInteger.valueOf(a)),sum_b[1].multiply(BigInteger.valueOf(b)));
ans=min(ans,res);
System.out.println(ans);
}
cin.close();
}
}