Skip to content

Commit

Permalink
aa
Browse files Browse the repository at this point in the history
  • Loading branch information
WangSenyuan committed Mar 27, 2024
1 parent 9f3569d commit 212959c
Show file tree
Hide file tree
Showing 8 changed files with 615 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/codeforces/set0/set7/set770/set773/a/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
You are an experienced Codeforces user. Today you found out that during your activity on Codeforces you have made y
submissions, out of which x have been successful. Thus, your current success rate on Codeforces is equal to x / y.

Your favorite rational number in the [0;1] range is p / q. Now you wonder: what is the smallest number of submissions
you have to make if you want your success rate to be p / q?

### ideas

### solution

This problem can be solved using binary search without any special cases. You can also solve it using a formula,
handling a couple of special cases separately.

If our success rate is p / q, it means we have pt successful submissions out of qt for some t. Since p / q is already
irreducible, t has to be a positive integer.

Let's reformulate things a bit. Initially we have x successful submissions and y - x unsuccessful ones. Suppose we fix
t, and in the end we want to have pt successful submissions and qt - pt unsuccessful ones. It's clear we can achieve
that if pt ≥ x and qt - pt ≥ y - x, since we can only increase both the number of successful and unsuccessful
submissions.

Note that both inequalities have constant right hand side, and their left hand side doesn't decrease as t increases.
Therefore, if the inequalities are satisfied for some t, they will definitely be satisfied for larger t as well.

It means we can apply binary search to find the lowest value of t satisfying the inequality. Then, the answer to the
problem is qt - y. If even for very large t the inequalities are not satisfied, the answer is -1.

It can be proved that one "very large" value of t is t = y — that is, if the inequalities are not satisfied for t = y,
then they cannot be satisfied for any value of t. Alternatively, picking t = 109 works too, since y ≤ 109.

Actually, inequalities pt ≥ x and qt - pt ≥ y - x are easy to solve by hand. From pt ≥ x it follows that . From qt -
pt ≥ y - x it follows that . In order to satisfy both inequalities, t has to satisfy .

Don't forget that t has to be integer, so the division results have to be rounded up to the nearest integer. In general,
if we want to find rounded up where both a and b are positive integers, the usual way to do that is to calculate (a +
b - 1)/ b, where "/" is the standard integer division (rounded down).

In this solution, cases when p / q = 0 / 1 or p / q = 1 / 1 have to be handled separately.
135 changes: 135 additions & 0 deletions src/codeforces/set0/set7/set770/set773/a/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package main

import (
"bufio"
"bytes"
"fmt"
"os"
"sort"
)

func main() {
reader := bufio.NewReader(os.Stdin)

tc := readNum(reader)
var buf bytes.Buffer

for tc > 0 {
tc--
nums := readNNums(reader, 4)
res := solve(nums[0], nums[1], nums[2], nums[3])
buf.WriteString(fmt.Sprintf("%d\n", res))
}

fmt.Print(buf.String())
}

func readString(reader *bufio.Reader) string {
s, _ := reader.ReadString('\n')
for i := 0; i < len(s); i++ {
if s[i] == '\n' || s[i] == '\r' {
return s[:i]
}
}
return s
}

func readNInt64s(reader *bufio.Reader, n int) []int64 {
res := make([]int64, n)
s, _ := reader.ReadBytes('\n')

var pos int

for i := 0; i < n; i++ {
pos = readInt64(s, pos, &res[i]) + 1
}

return res
}

func readInt64(bytes []byte, from int, val *int64) int {
i := from
var sign int64 = 1
if bytes[i] == '-' {
sign = -1
i++
}
var tmp int64
for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
tmp = tmp*10 + int64(bytes[i]-'0')
i++
}
*val = tmp * sign
return i
}

func readInt(bytes []byte, from int, val *int) int {
i := from
sign := 1
if bytes[i] == '-' {
sign = -1
i++
}
tmp := 0
for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
tmp = tmp*10 + int(bytes[i]-'0')
i++
}
*val = tmp * sign
return i
}

func readNum(reader *bufio.Reader) (a int) {
bs, _ := reader.ReadBytes('\n')
readInt(bs, 0, &a)
return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
res := readNNums(reader, 2)
a, b = res[0], res[1]
return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
res := readNNums(reader, 3)
a, b, c = res[0], res[1], res[2]
return
}

func readNNums(reader *bufio.Reader, n int) []int {
res := make([]int, n)
x := 0
bs, _ := reader.ReadBytes('\n')
for i := 0; i < n; i++ {
for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
x++
}
x = readInt(bs, x, &res[i])
}
return res
}

const oo = 1 << 30

func solve(x int, y int, p int, q int) int {

check := func(t int) bool {
a := p * t
b := q * t
return a >= x && b-a >= y-x
}

t := sort.Search(y+1, check)
if t > y {
return -1
}
return q*t - y
}

func gcd(a, b int) int {
for b > 0 {
a, b = b, a%b
}
return a
}
23 changes: 23 additions & 0 deletions src/codeforces/set0/set7/set770/set773/a/solution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import "testing"

func runSample(t *testing.T, x int, y int, p int, q int, expect int) {
res := solve(x, y, p, q)

if res != expect {
t.Fatalf("Sample expect %d, but got %d", expect, res)
}
}

func TestSample1(t *testing.T) {
x, y, p, q := 3, 10, 1, 2
expect := 4
runSample(t, x, y, p, q, expect)
}

func TestSample2(t *testing.T) {
x, y, p, q := 7, 14, 3, 8
expect := 10
runSample(t, x, y, p, q, expect)
}
55 changes: 55 additions & 0 deletions src/codeforces/set0/set7/set770/set773/b/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
### ideas

1. 其他人的时间是固定的,只需要考虑是否解决了某道题
2. 增加x个人,分母 + x
3. 考虑三种情况
4. 第一个中A错,B对的情况,新账号只能提交错误答案(这种情况下,有可能会增加B的分数)
5. 第二种情况A错, B错的情况,也只能提交错误答案
6. 第三种A对,B错的情况,这种情况提交错误答案,对A肯定是有利的,但提交正确答案,却不一定不利(需要仔细计算)
7. 第四种情况A对B对的情况,
8. 如果A更快完成,那么提交错误答案更有利,通过错误答案,增加分数,因为A更快完成,减少的比例更少,进而分数更好
9. 如果B更快完成,那么提交正确答案更有利,通过正确答案,减低分数,因为B更快完成,减少的比例更大,

### solution

Dynamic problem scoring used to be used more often in Codeforces rounds, including some tournament rounds like VK Cup
2015 Finals.

Once you read the problem statement carefully, the problem itself isn't overly difficult.

Consider new accounts Vasya puts into play. Correct solutions to which problems does he submit from these new accounts?

If Vasya hasn't solved a problem, he can't submit correct solutions to it.
If Vasya has solved a problem which Petya hasn't solved, then clearly Vasya wants the maximum point value of this
problem to be as high as possible, thus it doesn't make sense to submit its solution from the new accounts.
Suppose Vasya solved the problem at minute v, Petya solved it at minute p and the problem's maximum point value is m,
then Vasya's and Petya's scores for this problem are m·(1 - v / 250) and m·(1 - p / 250), respectively. Let's denote the
difference between these values by d = m·(p - v)/ 250. Vasya wants to maximize this value.
If p - v is positive (that is, Vasya solved the problem faster than Petya), then d is maximized when m is maximized. To
maximize m, Vasya shouldn't submit correct solutions to this problem from the new accounts.
On the other hand, if p - v is negative (that is, Petya solved the problem faster than Vasya), then d is maximized when
m is minimized. To minimize m, Vasya should submit correct solutions to this problem from the new accounts.
Finally, if p - v is zero (that is, Petya and Vasya solved the problem at the same moment), then d = 0 for any value of
m, so it doesn't matter if Vasya submits correct solutions to this problem or not.
It follows from the above that Vasya should always do the same for all new accounts he puts into play.

Let's iterate over x — the number of new accounts Vasya puts into play, starting from 0. Then we can determine what
solutions Vasya should submit from these accounts using the reasoning above. Then we can calculate the maximum point
values of the problems, and then the number of points Vasya and Petya will score. If Vasya's score is higher than Petya'
s score, then the answer is x, otherwise we increase x by one and continue.

When do we stop? If Vasya submits solutions to a problem from the new accounts, then after putting at least n accounts
into play the maximum point value of this problem will reach 500 and won't change anymore. If Vasya doesn't, then after
putting at least 31n accounts into play the maximum point value of this problem will reach 3000 and won't change
anymore. Therefore, if x exceeds 31n, we can stop and output -1.

Note that we can't find the value of x using binary search due to the fact that Vasya can't submit solutions to the
problems he hasn't solved. That is, more accounts do not mean more profit. For example, consider the following test
case:

3
0 -1 -1 -1 -1
-1 0 -1 -1 -1
-1 0 -1 -1 -1
If Vasya doesn't use any new accounts, his score will be 1000, while Petya's score will be 500. If Vasya uses at least
61 accounts, both his and Petya's score will be 3000.
Loading

0 comments on commit 212959c

Please sign in to comment.