NOIP2002-2017普及组题解

虽然普及组一般都是暴力省一,但是有一些题目还是挺难的qwq个人觉得能进TG的题目会在前面打上'*'

NOIP2002(clear)

 1 #include
 2 using namespace std;
 3 int main(){
 4     std::ios::sync_with_stdio(false);
 5     double Sn = 0;
 6     int k , i = 1;
 7     cin >> k;
 8     while(Sn <= k)    Sn += 1.0 / i++;
 9     cout << --i;
10     return 0;
11 }
级数求和
 1 //递推
 2 #include
 3 using namespace std;
 4 long long num[21][21];
 5 int dir[8][2] = {1,2,1,-2,-1,2,-1,-2,2,1,2,-1,-2,-1,-2,1};
 6 int main()
 7 {
 8     ios::sync_with_stdio(false);
 9     int a , b , c , d;
10     cin >> a >> b >> c >> d;
11     for(int i = 0 ; i <= a ; i++)
12         for(int j = 0 ; j <= b ; j++)
13         {
14             int f = 1;
15             for(int k = 0 ; k < 8 && f ; k++)
16                 if(c + dir[k][0] == i && d + dir[k][1] == j)    f = 0;
17             if(f && (c != i || d != j))
18                 if(i + j)    num[i][j] = num[i ? i - 1 : 0][j] + num[i][j ? j - 1 : 0];
19                 else    num[i][j] = 1;
20         }
21     cout << num[a][b];
22     return 0;
23 }
过河卒
 1 //递归
 2 #include
 3 using namespace std;
 4 int num[21] , cou , n;
 5 bool vis[21];
 6 bool ifZ(int a)
 7 {
 8     if(a == 1 || !a)    return false;
 9     for(int i = 2 ; i * i <= a ; i++)
10         if(a % i == 0)    return false;
11     return true;
12 }
13 void dfs(int a , int b , int c)
14 {
15     if(!a)
16     {
17         if(ifZ(b))    cou++;
18         return;
19     }
20     for(int i = c ; i <= n - a ; i++)
21         if(!vis[i])
22         {
23             vis[i] = 1;
24             dfs(a - 1 , b + num[i] , i + 1);
25             vis[i] = 0;
26         }
27 }
28 int main()
29 {
30     std::ios::sync_with_stdio(false);
31     int k;
32     cin >> n >> k;
33     for(int i = 0 ; i < n ; i++)    cin >> num[i];
34     dfs(k , 0 , 0);
35     cout << cou;
36     return 0;
37 }
选数
 1 //按位搜索
 2 #include
 3 using namespace std;
 4 multimap < char , char > rule;
 5 bool times[31][10];
 6 int num[31] = {1 , 1};
 7 int dfs(char a , int b)
 8 {
 9     if(times[b][a - '0'])    return 0;
10     times[b][a - '0'] = 1;
11     int sum = 1;
12     map < char , char > :: iterator iter = rule.find(a);
13     for(int i = 0 ; i != rule.count(a) ; ++i , ++iter)
14         sum += dfs(iter -> second , b);
15     return sum;
16 }
17 int main()
18 {
19     string s;
20     int n;
21     for(cin >> s >> n ; n ; n--){
22         char a , b;
23         cin >> a >> b;
24         rule.insert(make_pair(a , b));
25     }
26     for(int i = 0 ; i < s.size() ; i++)
27     {
28         int k = dfs(s[i] , i);
29         for(int i = 1 ; i <= num[0] ; i++)    num[i] *= k;
30         for(int i = 1 ; i <= num[0] ; i++)
31             if(num[i] >= 10)
32             {
33                 num[i + 1] += num[i] / 10;
34                 num[i] %= 10;
35                 if(i == num[0])    num[0]++;
36             }
37     }
38     while(num[0]--)    cout << num[num[0] + 1];
39     return 0;
40 }
产生数

NOIP2003(clear)

 1 //卡特兰数
 2 #include
 3 #define ll long long
 4 using namespace std;
 5 inline ll fast_read()
 6 {
 7     char c = getchar();
 8     ll a = 0;
 9     int k = 0;
10     while(!isdigit(c))
11     {
12         if(c == '-')    k = 1;
13         c = getchar();
14     }
15     while(isdigit(c))    a = (a << 3) + (a << 1) + c - '0' , c = getchar();
16     return k ? -a : a;
17 }
18 inline void fast_print(ll x)
19 {
20     int num[1001] , dirN = -1;
21     if(x < 0)    putchar('-') , x = -x;
22     while(x)    num[++dirN] = x % 10 , x /= 10;
23     if(dirN == -1)    putchar('0');
24     while(dirN + 1)    putchar(num[dirN--] + 48);
25     putchar('\n');
26 }
27 int num[19] = {1 , 1};
28 int main()
29 {
30     int n = fast_read();
31     for(int i = 2 ; i <= n ; i++)
32         for(int j = 0 ; j < n ; j++)
33             num[i] += num[j] * num[i - j - 1];
34     cout << num[n];
35     return 0;
36 }
 1 //注意最后的0:0
 2 #include
 3 using namespace std;
 4 int ans[2500][2];
 5 int main()
 6 {
 7     string s;
 8     int W11 = 0 , L11 = 0 , W21 = 0 , L21 = 0 , dirA = 0;
 9     while(cin >> s)
10     {
11         int ifE = 0;
12         for(int i = 0 ; i < s.size() && !ifE ; i++)
13         {
14             if(s[i] == 'W')
15             {
16                 W11++;
17                 W21++;
18                 if(W11 >= 11 && W11 - L11 >= 2)
19                 {
20                     cout << W11 << ":" << L11 << endl;
21                     W11 = L11 = 0;
22                 }
23                 if(W21 >= 21 && W21 - L21 >= 2)
24                 {
25                     ans[dirA][0] = W21;
26                     ans[dirA++][1] = L21;
27                     W21 = L21 = 0;
28                 }
29             }
30             else    if(s[i] == 'L')
31             {
32                 L11++;
33                 L21++;
34                 if(L11 >= 11 && L11 - W11 >= 2)
35                 {
36                     cout << W11 << ":" << L11 << endl;
37                     W11 = L11 = 0;
38                 }
39                 if(L21 >= 21 && L21 - W21 >= 2)
40                 {
41                     ans[dirA][0] = W21;
42                     ans[dirA++][1] = L21;
43                     W21 = L21 = 0;
44                 }
45             }
46             else    ifE = 1;
47         }
48         if(ifE)    break;
49     }
50     cout << W11 << ":" << L11 << endl;
51     for(int i = 0 ; i < dirA ; i++)    cout << endl << ans[i][0] << ":" << ans[i][1];
52     cout << endl << W21 << ":" << L21;
53     return 0;
54 }
乒乓球
 1 //区间DP
 2 #include
 3 using namespace std;
 4 int num[101] , maxN[101][101][10] , minN[101][101][10];
 5 inline int max(int a , int b){
 6     return a > b ? a : b;
 7 }
 8 inline int min(int a , int b){
 9     return a < b ? a : b;
10 }
11 int main(){
12     memset(minN , 0x3f , sizeof(minN));
13     int N , M;
14     cin >> N >> M;
15     for(int i = 1 ; i <= N ; i++)
16     {
17         cin >> num[i];
18         num[i + N] = num[i];
19     }
20     for(int i = 1 ; i <= N << 1 ; i++)
21         for(int j = i ; j <= N << 1 ; j++)
22             minN[i][j][1] = maxN[i][j][1]
23             = ((maxN[i][j - 1][1] + num[j]) % 10 + 10) % 10;
24     for(int k = 2 ; k <= M ; k++)
25         for(int i = 1 ; i <= (N << 1) - k + 1 ; i++)
26             for(int j = i + k - 1 ; j <= N << 1 && j - i + 1 <= N ; j++)
27                 for(int m = i ; m < j ; m++)
28                     for(int n = max(1 , k - j + m) ; n < k && n <= m - i + 1 ; n++)
29                     {
30                         maxN[i][j][k] = max(maxN[i][j][k] , maxN[i][m][n] * maxN[m + 1][j][k - n]);
31                         minN[i][j][k] = min(minN[i][j][k] , minN[i][m][n] * minN[m + 1][j][k - n]);
32                     }
33     int maxM = 0 , minM = 0x3f3f3f3f;
34     for(int i = 1 ; i <= N ; i++)
35     {
36         maxM = max(maxM , maxN[i][i + N - 1][M]);
37         minM = min(minM , minN[i][i + N - 1][M]);
38     }
39     cout << minM << endl << maxM;
40     return 0;
41 }
数字游戏
 1 //第一问用对数函数得答案,第二问高精快速幂
 2 #include
 3 using namespace std;
 4 int num1[502] = {0 , 2} , num2[502] , num3[502] = {0 , 1};
 5 int main()
 6 {
 7     std::ios::sync_with_stdio(false);
 8     int p;
 9     cin >> p;
10     cout << floor(log10(2) * p + 1) << endl;
11     while(p)
12     {
13         if(p & 1)
14         {
15             for(int i = 1 ; i <= 500 ; i++)
16                 for(int j = 1 ; j <= 501 - i ; j++)
17                 {
18                     num2[i + j - 1] += num1[i] * num3[j];
19                     if(num2[i + j - 1] >= 10)
20                     {
21                         if(i + j - 1 < 500)    num2[i + j] += num2[i + j - 1] / 10;
22                         num2[i + j - 1] %= 10;
23                     }
24                 }
25             for(int i = 500 ; i ; i--)
26             {
27                 num3[i] = num2[i];
28                 num2[i] = 0;
29             }
30         }
31         for(int i = 1 ; i <= 500 ; i++)
32             for(int j = 1 ; j <= 501 - i ; j++)
33             {
34                 num2[i + j - 1] += num1[i] * num1[j];
35                 if(num2[i + j - 1] >= 10)
36                 {
37                     if(i + j - 1 < 500)    num2[i + j] += num2[i + j - 1] / 10;
38                     num2[i + j - 1] %= 10;
39                 }
40             }
41         for(int i = 500 ; i ; i--)    
42         {
43             num1[i] = num2[i];
44             num2[i] = 0;
45         }
46         p >>= 1;
47     }
48     num3[1]--;
49     for(int i = 500 ; i ; i--)
50     {
51         cout << num3[i];
52         if((i - 1) % 50 == 0)    cout << endl;
53     }
54     return 0;
55 }
麦森数

NOIP2004(clear)

 1 #include
 2 using namespace std;
 3 int main()
 4 {
 5     int maxN = 7 , maxD = 0;
 6     for(int i = 1 ; i <= 7 ; i++)
 7     {
 8         int a , b;
 9         cin >> a >> b;
10         if(a + b > maxN)
11         {
12             maxN = a + b;
13             maxD = i;
14         }
15     }
16     cout << maxD;
17     return 0;
18 }
不高兴的津津
 1 //模拟
 2 #include
 3 using namespace std;
 4 struct hs{
 5     int num , x , y;
 6 }ans[401];
 7 bool cmp(hs a , hs b)
 8 {
 9     return a.num > b.num;
10 }
11 int main()
12 {
13     int n , m , p , dirH = 0 , i = 1 , pri , nowX , nowY;
14     cin >> n >> m >> p;
15     for(int i = 1 ; i <= n ; i++)
16         for(int j = 1 ; j <= m ; j++)
17         {
18             int a;
19             cin >> a;
20             if(a)
21             {
22                 ans[dirH].num = a;
23                 ans[dirH].x = i;
24                 ans[dirH++].y = j;
25             }
26         }
27     sort(ans , ans + dirH , cmp);
28     if(ans[0].x * 2 + 1> p)
29     {
30         cout << 0;
31         return 0;
32     }
33     p -= ans[0].x + 1;
34     pri = ans[0].num;
35     nowX = ans[0].x;
36     nowY = ans[0].y;
37     while(i < dirH && p - abs(nowX - ans[i].x) - abs(nowY - ans[i].y) - ans[i].x - 1 >= 0)
38     {
39         p -= abs(nowX - ans[i].x) + abs(nowY - ans[i].y) + 1;
40         nowX = ans[i].x;
41         nowY = ans[i].y;
42         pri += ans[i++].num;
43     }
44     cout << pri;
45     return 0;
46 }
花生采摘
 1 //乱搞
 2 #include
 3 using namespace std;
 4 int n;
 5 char m[11][1024];
 6 void hx(int a , int b)
 7 {
 8     if(a == n)    cout << m[a][b];
 9     else{
10         hx(a + 1 , 2 * b);
11         hx(a + 1 , 2 * b + 1);
12         if(m[a + 1][2 * b] == 'B' && m[a + 1][2 * b + 1] == 'B')
13             m[a][b] = 'B';
14         else    if(m[a + 1][2 * b] == 'I' && m[a + 1][2 * b + 1] == 'I')    
15                 m[a][b] = 'I';
16         else    m[a][b] = 'F';
17         cout << m[a][b];
18     }
19 }
20 int main()
21 {
22     string s;
23     cin >> n >> s;
24     for(int i = 0 ; i < s.size() ; i++)
25         if(s[i] == '1')    m[n][i] = 'I';
26         else    m[n][i] = 'B';
27     hx(0 , 0);
28     return 0;
29 }
FBI树
 1 //在这一道题中认识了next_permutation()
 2 #include
 3 using namespace std;
 4 int num[10001];
 5 int main()
 6 {
 7     int n , k;
 8     cin >> n >> k;
 9     for(int i = 0 ; i < n ; i++)    cin >> num[i];
10     for(int i = 0 ; i < k ; i++)    next_permutation(num , num + n);
11     for(int i = 0 ; i < n ; i++)    cout << num[i] << " ";
12     return 0;
13 }
火星人

NOIP2005(clear)

 1 #include
 2 using namespace std;
 3 int num[10];
 4 int main(){
 5     for(int i = 0 ; i < 10 ; i++)    cin >> num[i];
 6     int a , cou = 0;
 7     cin >> a;
 8     for(int i = 0 ; i < 10 ; i++)
 9         if(num[i] - a <= 30)    cou++;
10     cout << cou;
11     return 0;
12 }
陶陶摘苹果
 1 //线段树练习题(划掉
 2 #include
 3 using namespace std;
 4 bool vis[10001];
 5 int main()
 6 {
 7     std::ios::sync_with_stdio(false);
 8     int L , m , cou = 0;
 9     for(cin >> L >> m ; m ; m--)
10     {
11         int a , b;
12         for(cin >> a >> b ; a <= b ; a++)    vis[a] = 1;
13     }
14     for( ; L + 1 ; L--)    if(!vis[L])    cou++;
15     cout << cou;
16     return 0;
17 }
校门外的树
 1 //01背包
 2 #include
 3 using namespace std;
 4 int vis[1001];
 5 int main(){
 6     std::ios::sync_with_stdio(false);
 7     int T , M;
 8     for(cin >> T >> M ; M ; M--)
 9     {
10         int a , b;
11         cin >> a >> b;
12         for(int i = T ; i >= a ; i--)
13             vis[i] = max(vis[i] , vis[i - a] + b);
14     }
15     cout << vis[T];
16     return 0;
17 }
采药
 1 //考虑第一位在多少步内完成循环,然后考虑后两位在多少步内完成循环,递推下去找到答案
 2 #include
 3 //This code is written by Itst
 4 using namespace std;
 5 
 6 int K;
 7 struct Bignum{
 8     int a[502];
 9     Bignum(){
10         memset(a , 0 , sizeof(a));
11     }
12 
13     int& operator [](int x){
14         return a[x];
15     }
16     
17     void input(){
18         string s;
19         cin >> s;
20         for(int i = 1 ; i <= s.size() ; i++)
21             a[i] = s[s.size() - i] - '0';
22     }
23 
24     void output(){
25         for(int i = a[0] ; i ; i--)
26             putchar(a[i] + '0');
27     }
28 
29     Bignum operator *(Bignum b){
30         Bignum c;
31         c[0] = K;
32         for(int i = 1 ; i <= K ; i++)
33             for(int j = 1 ; j <= K ; j++)
34                 c[i + j - 1] += a[i] * b[j];
35         for(int i = 1 ; i <= K ; i++)
36             if(c[i] >= 10){
37                 c[i + 1] += c[i] / 10;
38                 c[i] %= 10;
39             }
40         return c;
41     }
42 
43     void operator *=(int b){
44         for(int i = 1 ; i <= a[0] ; i++)
45             a[i] *= b;
46         for(int i = 1 ; i <= a[0] ; i++)
47             if(a[i] >= 10){
48                 a[i + 1] += a[i] / 10;
49                 a[i] %= 10;
50                 if(i == a[0])
51                     ++a[0];
52             }
53     }
54 }ori , A , B , ans;
55 
56 int main(){
57 #ifndef ONLINE_JUDGE
58     freopen("1050.in" , "r" , stdin);
59     //freopen("1050.out" , "w" , stdout);
60 #endif
61     ori.input();
62     cin >> K;
63     ori[0] = K;
64     A = ori;
65     B = ori;
66     ans[0] = ans[1] = 1;
67     for(int i = 1 ; i <= K ; i++){
68         if((ori * A)[i] == ori[i])
69             continue;
70         B = A;
71         bool f = 0;
72         for(int j = 1 ; !f && j <= 50 ; j++){
73             A = A * B;
74             if((A * ori)[i] == ori[i]){
75                 ans *= j + 1;
76                 f = 1;
77             }
78         }
79         if(!f){
80             puts("-1");
81             return 0;
82         }
83     }
84     ans.output();
85     return 0;
86 }
*循环

NOIP2006(clear)

 1 #include
 2 using namespace std;
 3 int num[101];
 4 int main()
 5 {
 6     int n , cou = 1;
 7     cin >> n;
 8     for(int i = 0 ; i < n ; i++)    cin >> num[i];
 9     sort(num , num + n);
10     for(int i = 1 ; i < n ; i++)
11         if(num[i] != num[i - 1])    cou++;
12     cout << cou << endl << num[0];
13     for(int i = 1 ; i < n ; i++)
14         if(num[i] != num[i - 1])    cout << " " << num[i];
15     return 0;
16 }
明明的随机数
 1 //又是01背包
 2 #include
 3 using namespace std;
 4 int vis[30001];
 5 int main()
 6 {
 7     int n , t;
 8     for(cin >> n >> t ; t ; t--)
 9     {
10         int a , b;
11         cin >> a >> b;
12         for(int i = n - a ; i + 1 ; i--)
13         vis[i + a] = max(vis[i + a] , vis[i] + a * b);
14     }
15     cout << vis[n];
16     return 0;
17 }
开心的金明
 1 //模拟
 2 #include
 3 using namespace std;
 4 string now;
 5 int s , t , w;
 6 int check(){
 7     int dir = w;
 8     while(dir + 1 && now[dir] - 'a' + (w - dir) == t)
 9         dir--;
10     return dir;
11 }
12 int main()
13 {
14     cin >> s >> t >> w >> now;
15     s--;
16     t--;
17     w--;
18     for(int i = 1 ; i <= 5 ; i++){
19         int k = check();
20         if(k == -1)
21             return 0;
22         now[k]++;
23         while(++k <= w)
24             now[k] = now[k - 1] + 1;
25         cout << now << endl;
26     }
27      return 0;
28 }
Jam的计数法
 1 //二进制相关
 2 #include
 3 #define ll long long
 4 using namespace std;
 5 inline ll fast_read()
 6 {
 7     char c = getchar();
 8     ll a = 0;
 9     int k = 0;
10     while(!isdigit(c))
11     {
12         if(c == '-')    k = 1;
13         c = getchar();
14     }
15     while(isdigit(c))    a = (a << 3) + (a << 1) + c - '0' , c = getchar();
16     return k ? -a : a;
17 }
18 inline void fast_print(ll x)
19 {
20     int num[1001] , dirN = -1;
21     if(x < 0)    putchar('-') , x = -x;
22     while(x)    num[++dirN] = x % 10 , x /= 10;
23     if(dirN == -1)    putchar('0');
24     while(dirN + 1)    putchar(num[dirN--] + 48);
25 }
26 int main()
27 {
28     ll a = fast_read() , b = fast_read() , sum = 0 , d = 1;
29     while(b)
30     {
31         if(b & 1)    sum += d;
32         b >>= 1;
33         d *= a;
34     }
35     fast_print(sum);
36     return 0;
37 }
数列

NOIP2007(clear)

 1 //结构体排序
 2 #include
 3 using namespace std;
 4 struct stu{
 5     int chi , math , eng , tot , i;
 6     inline void input()
 7     {
 8         cin >> chi >> math >> eng;
 9         tot = chi + math + eng;
10     }
11 }ans[301];
12 bool cmp(stu a , stu b)
13 {
14     return a.tot > b.tot || a.tot == b.tot && a.chi > b.chi || a.tot == b.tot && a.chi == b.chi && a.i < b.i;
15 }
16 int main()
17 {
18     int n;
19     cin >> n;
20     for(int i = 0 ; i < n ; i++)
21     {
22         ans[i].input();
23         ans[i].i = i + 1;
24     }
25     sort(ans , ans + n , cmp);
26     for(int i = 0 ; i < 5 ; i++)
27         cout << ans[i].i << " " << ans[i].tot << endl;
28     return 0;
29 }
奖学金
 1 //贪心选能够搭配的最大的
 2 #include
 3 using namespace std;
 4 int num[30001];
 5 int main()
 6 {
 7     ios::sync_with_stdio(false);
 8     int n , k , m = 0 , cou = 0;
 9     cin >> n >> k;
10     for(int i = 0 ; i < k ; i++)    cin >> num[i];
11     sort(num , num + --k + 1);
12     while(m <= k)
13     {
14         cou++;
15         int sum = num[k--];
16         while(sum + num[m] <= n && m <= k)    sum += num[m++];
17     }
18     cout << cou;
19     return 0;
20 }
纪念品分组
 1 //条件判断练习题
 2 #include
 3 #define ll long long
 4 using namespace std;
 5 inline ll fast_read()
 6 {
 7     char c = getchar();
 8     ll a = 0;
 9     int k = 0;
10     while(!isdigit(c))
11     {
12         if(c == '-')    k = 1;
13         c = getchar();
14     }
15     while(isdigit(c))    a = (a << 3) + (a << 1) + c - '0' , c = getchar();
16     return k ? -a : a;
17 }
18 int main()
19 {
20     int M = fast_read() , S = fast_read() , T = fast_read() , t , s;
21     if(M / 10 * 60 >= S)
22         if(ceil(S / 60.0) > T)    cout << "No" << endl << T * 60;
23         else    cout << "Yes" << endl << (int)ceil(S / 60.0);
24     else    if(M / 10 >= T)    cout << "No" << endl << T * 60;
25     else{
26         t = M / 10;
27         s = M / 10 * 60;
28         M %= 10;
29         while(s < S && T > t && M >= 2 && T - t >= ceil((14 - M) / 4.0))
30         {
31             if(M < 10)    M += 4;
32             else{
33                 M -= 10;
34                 s += 60;
35             }
36             t++;
37         }
38         while(s < S && T > t)
39             if(T - t >= ceil((28 - M) / 4.0) && S - s >= 120)
40             {
41                 t += ceil((28 - M) / 4.0);
42                 s += 120;
43             }
44             else
45             {
46                 if(T - t >= ceil((14 - M) / 4.0) && ceil((14 - M) / 4.0) * 17 < 60 && S - s > ceil((14 - M) / 4.0) * 17)
47                 {
48                     t += ceil((14 - M) / 4.0);
49                     s += 60;
50                 }
51                 while(s < S && T > t++)    s += 17;
52             }
53         if(s >= S)    cout << "Yes" << endl << t;
54         else    cout << "No" << endl << s;
55     }
56     return 0;
57 }
守望者的逃离
 1 //递推
 2 #include
 3 #define ll long long
 4 using namespace std;
 5 inline ll fast_read()
 6 {
 7     char c = getchar();
 8     ll a = 0;
 9     int k = 0;
10     while(!isdigit(c))
11     {
12         if(c == '-')    k = 1;
13         c = getchar();
14     }
15     while(isdigit(c))    a = (a << 3) + (a << 1) + c - '0' , c = getchar();
16     return k ? -a : a;
17 }
18 inline void fast_print(ll x)
19 {
20     int num[1001] , dirN = -1;
21     if(x < 0)    putchar('-') , x = -x;
22     while(x)    num[++dirN] = x % 10 , x /= 10;
23     if(dirN == -1)    putchar('0');
24     while(dirN + 1)    putchar(num[dirN--] + 48);
25 }
26 int num[201][999];
27 int main()
28 {
29     int a = fast_read();
30     for(int i = 1 ; i <= a ; i++)
31     {
32         num[i][0] = num[i - 1][0] + 1;
33         num[i][1] = 2;
34         for(int j = 1 ; j <= num[i - 1][0] ; j++)
35         {
36             num[i][j] += num[i - 1][j] * 2;
37             if(num[i][j] >= 10)
38             {
39                 num[i][j + 1]++;
40                 num[i][j] -= 10;
41             }
42         }
43         if(!num[i][num[i][0]])    num[i][0]--;
44     }
45     for(int i = num[a][0] ; i ; i--)
46         fast_print(num[a][i]);
47     return 0;
48 }
Hanoi双塔问题

NOIP2008(clear)

 1 #include
 2 using namespace std;
 3 int main()
 4 {
 5     int a , b , c , a1;
 6     char d;
 7     scanf("%d-%d-%d-%c" , &a1 , &b , &c , &d);
 8     a = a1 + b % 10 * 4 + b / 10 % 10 * 3 + b / 100 * 2 + c % 10 * 9 + c / 10 % 10 * 8 + c / 100 % 10 * 7 + c / 1000 % 10 * 6 + c / 10000 * 5;
 9     if(a % 11 == 10 && d == 'X' || a % 11 == d - '0')    printf("Right");
10     else    printf("%d-%d-%d-%c" , a1 , b , c , a % 11 == 10 ? 'X' : a % 11 + '0');
11     return 0;
12 }
ISBN号码
 1 //排序
 2 #include
 3 using namespace std;
 4 struct hl{
 5     int i , num;
 6 }h[1001] , l[1001];
 7 bool cmp1(hl a , hl b)
 8 {
 9     return a.num > b.num;
10 }
11 bool cmp2(hl a , hl b)
12 {
13     return a.i < b.i;
14 }
15 int main()
16 {
17     ios::sync_with_stdio(false);
18     int n , m , k , q , d;
19     cin >> n >> m >> k >> q >> d;
20     for(int i = 1 ; i <= n ; i++)    h[i].i = i;
21     for(int i = 1 ; i <= m ; i++)    l[i].i = i;
22     for(int i = 0 ; i < d ; i++)
23     {
24         int a , b , c , d;
25         cin >> a >> b >> c >> d;
26         if(a == c)    l[min(b , d)].num++;
27         else    h[min(a , c)].num++;
28     }
29     sort(h , h + n , cmp1);
30     sort(h , h + k , cmp2);
31     for(int i = 0 ; i < k ; i++)
32     {
33         if(i)    cout << " ";
34         cout << h[i].i;
35     }
36     cout << endl;
37     sort(l , l + m , cmp1);
38     sort(l , l + q , cmp2);
39     for(int i = 0 ; i < q ; i++)
40     {
41         if(i)    cout << " ";
42         cout << l[i].i;
43     }
44     return 0;
45 }
排座椅
 1 //递推
 2 #include
 3 using namespace std;
 4 int n , k , v[31][2] = {1};
 5 int main(){
 6     cin >> n >> k;
 7     for(int i = 0 ; i < k ; i++)
 8     {
 9         for(int j = 0 ; j < n ; j++)
10             if(v[j][0])
11             {
12                 v[(j + 1) % n][1] += v[j][0];
13                 v[(j + n - 1) % n][1] += v[j][0];
14             }
15         for(int j = 0 ; j < n ; j++)
16         {
17             v[j][0] = v[j][1];
18             v[j][1] = 0;
19         }
20     }
21     cout << v[0][0];
22     return 0;
23 }
传球游戏
 1 //这个模拟可还行
 2 #include
 3 using namespace std;
 4 char m[501][501];
 5 char ex[6][8] = {"\0\0+---+" , "\0/   /|" , "+---+ |" , "|   | +" , "|   |/\0" , "+---+\0\0"
 6 };
 7 int num[101][101];
 8 int main(){
 9     ios::sync_with_stdio(false);
10     memset(m , '.' , sizeof(m));
11     int a , b;
12     cin >> a >> b;
13     int k = 0 , l = b * 4 + a * 2 + 1;
14     for(int i = 1 ; i <= a ; i++)
15         for(int j = 1 ; j <= b ; j++)
16         {
17             cin >> num[i][j];
18             k = max(k , 2 * (a - i) + 3 * num[i][j] + 3);
19         }
20     for(int i = 1 ; i <= a ; i++)
21         for(int j = 1 ; j <= b ; j++)
22         {
23             int l = 4 * j - 3 + 2 * (a - i) , h = k - 2 * (a - i);
24             while(num[i][j]--){
25                 for(int p = h - 5 ; p <= h ; p++)
26                     for(int q = l ; q - l < 7 ; q++)
27                         if(ex[5 + p - h][q - l])    m[p][q] = ex[5 + p - h][q - l];
28                 h -= 3;
29             }
30         }
31     for(int i = 1 ; i <= k ; i++)
32     {
33         if(i - 1)    cout << endl;
34         for(int j = 1 ; j <= l ; j++)    cout << m[i][j];
35     }
36     return 0;
37 }
立体图

NOIP2009(clear)

 1 //注意细节
 2 #include
 3 using namespace std;
 4 int main()
 5 {
 6     int n;
 7     cin >> n;
 8     for(int i = n ; i + 1 ; i--)
 9     {
10         int a;
11         cin >> a;
12         if(!a)    continue;
13         if(i - n && a > 0)    cout << "+";
14         if(a != 1)    
15             if(a != -1 || !i)    cout << a;
16             else    cout << "-";
17         else    if(!i)    cout << 1;
18         if(i)    cout << "x";
19         if(i - 1 && i)    cout << "^" << i;
20     }
21     return 0;
22 }
多项式输出
 1 //排序
 2 #include
 3 using namespace std;
 4 struct can{
 5     int bmh , score;
 6 }ans[5001];
 7 bool cmp(can a , can b)
 8 {
 9     if(a.score == b.score)
10         return a.bmh < b.bmh;
11     return a.score > b.score;
12 }
13 int main()
14 {
15     std::ios::sync_with_stdio(false);
16     int n , m;
17     cin >> n >> m;
18     for(int i = 0 ; i < n ; i++)
19         cin >> ans[i].bmh >> ans[i].score;
20     sort(ans , ans + n , cmp);
21     m *= 1.5;
22     while(ans[m - 1].score == ans[m].score)    m++;
23     cout << ans[m - 1].score << " " << m << endl;
24     for(int i = 0 ; i < m ; i++)    cout << ans[i].bmh << " " << ans[i].score << endl;
25     return 0;
26 }
分数线划定
 1 //筛质因数
 2 #include
 3 #define inf 0x7fffffff
 4 //This code is written by Itst
 5 using namespace std;
 6 
 7 inline int read(){
 8     int a = 0;
 9     bool f = 0;
10     char c = getchar();
11     while(c != EOF && !isdigit(c)){
12         if(c == '-')
13             f = 1;
14         c = getchar();
15     }
16     while(c != EOF && isdigit(c)){
17         a = (a << 3) + (a << 1) + (c ^ '0');
18         c = getchar();
19     }
20     return f ? -a : a;
21 }
22 
23 int maxN[10010] , num[10010] , N , m1 , m2;
24 
25 int main(){
26 #ifdef OJ
27     freopen("1069.in" , "r" , stdin);
28     //freopen("1069.out" , "w" , stdout);
29 #endif
30     N = read();
31     m1 = read();
32     m2 = read();
33     for(int i = 1 ; i <= N ; i++)
34         num[i] = read();
35     for(int i = 2 ; i * i <= m1 ; i++)
36         if(m1 % i == 0){
37             int cnt = 0;
38             while(m1 % i == 0){
39                 m1 /= i;
40                 cnt++;
41             }
42             cnt *= m2;
43             for(int j = 1 ; j <= N ; j++){
44                 int t = 0;
45                 while(num[j] % i == 0){
46                     num[j] /= i;
47                     ++t;
48                 }
49                 if(!t)
50                     maxN[j] = inf;
51                 else
52                     maxN[j] = max(maxN[j] , cnt / t + (cnt % t ? 1 : 0));
53             }
54         }
55     if(m1 - 1)
56         for(int j = 1 ; j <= N ; j++){
57             int t = 0;
58             while(num[j] % m1 == 0){
59                 num[j] /= m1;
60                 ++t;
61             }
62             if(!t)
63                 maxN[j] = inf;
64             else
65                 maxN[j] = max(maxN[j] , m2 / t + (m2 % t ? 1 : 0));
66         }
67     int ans = inf;
68     for(int i = 1 ; i <= N ; i++)
69         ans = min(ans , maxN[i]);
70     cout << (ans == inf ? -1 : ans);
71     return 0;
72 }
*细胞分裂
 1 //三方过一千
 2 #include
 3 using namespace std;
 4 int dp[1001] , pri[1001][1001] , cost[1001];
 5 int main(){
 6     memset(dp , -0x3f , sizeof(dp));
 7     dp[0] = 0;
 8     int N , M , P;
 9     cin >> N >> M >> P;
10     for(int i = 1 ; i <= N ; i++)
11         for(int j = 1 ; j <= M ; j++)
12             cin >> pri[i][j];
13     for(int i = 1 ; i <= N ; i++)
14         cin >> cost[i];
15     for(int i = 0 ; i < M ; i++)
16         for(int j = 1 ; j <= N ; j++){
17             int t = j , sum = -cost[j];
18             for(int m = 1 ; m <= P && m + i <= M ; m++){
19                 dp[m + i] = max(dp[m + i] , dp[i] + (sum += pri[t][m + i]));
20                 t = t % N + 1;
21             }
22         }
23     cout << dp[M];
24     return 0;
25 }
道路游戏

NOIP2010(clear)

 1 #include
 2 using namespace std;
 3 inline int count_num(int a){
 4     int sum = 0;
 5     while(a)
 6     {
 7         if(a % 10 == 2)    sum++;
 8         a /= 10;
 9     }
10     return sum;
11 }
12 int main(){
13     int N , M , sum = 0;
14     for(cin >> N >> M ; N <= M ; N++)    sum += count_num(N);
15     cout << sum;
16     return 0;
17 }
数字统计
 1 //贪心
 2 #include
 3 using namespace std;
 4 int main()
 5 {
 6     int i , j , t = 0 , f = 0 , m[100] = {0} , n[10000] = {0} , nhead = 0;
 7     cin >> i >> j;
 8     for(int k = 0 ; k < i ; k++)
 9     {
10         cin >> n[k];
11         if(nhead < j)
12         {
13             m[nhead] = n[nhead];
14             nhead++;
15         }
16     }
17     while(f != j)
18     {
19         t++;
20         f = 0;
21         for(int k = 0 ; k < j ; k++)
22             if(--m[k] <= 0)
23                 if(nhead < i)
24                 {
25                     m[k] = n[nhead];
26                     nhead++;
27                 }
28                 else
29                     f++;
30     }
31     cout << t;
32     return 0;
33 }
接水问题
 1 //贪心+DP
 2 #include
 3 #define P pair < int , int >
 4 using namespace std;
 5 P dis[100001];
 6 int maxN[100001];
 7 bool cmp(P a , P b){
 8     return a.first < b.first;
 9 }
10 inline int max(int a , int b){
11     return a > b ? a : b;
12 }
13 inline int min(int a , int b){
14     return a < b ? a : b;
15 }
16 int main()
17 {
18     ios::sync_with_stdio(false);
19     int x1 , y1 , x2 , y2 , N , minN = 2147483647;
20     cin >> x1 >> y1 >> x2 >> y2 >> N;
21     for(int i = 1 ; i <= N ; i++)
22     {
23         int a , b;
24         cin >> a >> b;
25         dis[i].first = (a - x1) * (a - x1) + (b - y1) * (b - y1);
26         dis[i].second = (a - x2) * (a - x2) + (b - y2) * (b - y2);
27     }
28     sort(dis + 1 , dis + N + 1 , cmp);
29     for(int i = N ; i ; i--)    maxN[i] = max(maxN[i + 1] , dis[i].second);
30     for(int i = 0 ; i <= N ; i++)
31         if(dis[i].first ^ dis[i + 1].first)
32             minN = min(dis[i].first + maxN[i + 1] , minN);
33     cout << minN;
34      return 0;
35 }
导弹拦截
 1 //震惊!puts("0")竟然没分!
 2 //第二问贪心选择每行第二大的数中最大的那个
 3 #include
 4 using namespace std;
 5 int num[501][501];
 6 int main(){
 7     int N , maxN = 0 , dirA , dirB , maxA = 0 , maxDirA , maxB = 0 , maxDirB;
 8     cin >> N;
 9     for(int i = 1 ; i < N ; i++)
10         for(int j = i + 1 ; j <= N ; j++)
11         {
12             cin >> num[i][j];
13             num[j][i] = num[i][j];
14         }
15     for(int i = 1 ; i <= N ; i++)
16     {
17         int m = 0 , dir , mci = 0 , dirci;
18         for(int j = 1 ; j <= N ; j++)
19             if(i ^ j)
20                 if(m < num[i][j])
21                     {
22                         mci = m;
23                         m = num[i][j];
24                         dirci = dir;
25                         dir = j;
26                     }
27                     else    if(mci < num[i][j])
28                     {
29                         mci = num[i][j];
30                         dirci = j;
31                     }
32         if(mci > maxN){
33             maxN = mci;
34             dirA = i;
35             dirB = dirci;
36         }
37     }
38     for(int i = 1 ; i <= N ; i++)
39         if(i ^ dirA && i ^ dirB && maxA < num[dirA][i])
40         {
41             maxA = num[dirA][i];
42             maxDirA = i;
43         }
44     for(int i = 1 ; i <= N ; i++)
45         if(i ^ dirB && i ^ dirA && i ^ maxDirA && maxB < num[dirB][i])
46         {
47             maxB = num[dirB][i];
48             maxDirB = i;
49         }
50     if(num[maxDirA][maxDirB] > num[dirA][dirB]){
51         cout << 0;
52         return 0;
53     }
54     for(int i = 1 ; i <= N ; i++)
55         if(i ^ dirA && i ^ dirB && i ^ maxDirA && i ^ maxDirB && (num[i][maxDirA] > maxN || num[i][maxDirB] > maxN))
56         {
57             int m = 0 , mDir;
58             for(int j = 1 ; j <= N ; j++)
59                 if(j ^ dirA && j ^ dirB && j ^ maxDirA && j ^ maxDirB && j ^ i && m < num[i][j])
60                 {
61                     m = num[i][j];
62                     mDir = j;
63                 }
64             if(num[mDir][dirA] > m || num[mDir][dirB] > m)
65             {
66                 cout << 0;
67                 return 0;
68             }
69         }
70     cout << 1 << endl << maxN;
71     return 0;
72 }
三国游戏

NOIP2011(clear)

 1 #include
 2 using namespace std;
 3 int main()
 4 {
 5     string s;
 6     cin >> s;
 7     if(s[0] == '-')
 8     {
 9         cout << '-';
10         s = string(s , 1 , s.size() - 1);
11     }
12     int f = 0;
13     for(int i = s.size() ; i ; i--)
14         if(f || s[i - 1] - '0')
15         {
16             cout << s[i - 1];
17             f = 1;
18         }
19     return 0;
20 }
数字反转
 1 #include
 2 using namespace std;
 3 char s1[10001] , s2[1000011];
 4 int l1 , l2;
 5 inline bool cmp(int i)
 6 {
 7     for(int j = 0 ; j < l1 ; j++)
 8         if(s1[j] != s2[j + i])    return false;
 9     return true;
10 }
11 int main()
12 {
13     int cou = 0 , couF = -1;
14     gets(s1);
15     gets(s2);
16     l1 = strlen(s1);
17     l2 = strlen(s2);
18     for(int i = 0 ; i < l1 ; i++)
19         if(s1[i] >= 'A' && s1[i] <= 'Z')    s1[i] += 'a' - 'A';
20     for(int i = 0 ; i < l2 ; i++)
21         if(s2[i] >= 'A' && s2[i] <= 'Z')    s2[i] += 'a' - 'A';
22     for(int i = 0 ; i <= l2 - l1 ; i++)
23         if(cmp(i) && (!i || s2[i - 1] == ' ') && (i == l2 - l1 || s2[l1 + i] == ' '))
24         {
25             cou++;
26             if(couF == -1)    couF = i;
27         }
28     if(cou)    cout << cou << " " << couF;
29     else    cout << -1;
30     return 0;
31 }
统计单词数
 1 //归并排序
 2 #include
 3 using namespace std;
 4 struct can{
 5     int sl , fs , i;
 6 }ans[200001] , win[100001] , lose[100001];
 7 int n;
 8 void gb()
 9 {
10     int dirA = 0 , dirB = 0;
11     for(int i = 0 ; i < 2 * n ; i++)
12         if(dirA != n && (dirB == n || win[dirA].fs > lose[dirB].fs || win[dirA].fs == lose[dirB].fs && win[dirA].i < lose[dirB].i))
13             ans[i] = win[dirA++];
14         else    ans[i] = lose[dirB++];
15 }
16 bool cmp(can a , can b)
17 {
18     return a.fs > b.fs || a.fs == b.fs && a.i < b.i;
19 }
20 int main()
21 {
22     ios::sync_with_stdio(false);
23     int r , q;
24     cin >> n >> r >> q;
25     for(int i = 0 ; i < 2 * n ; i++)    cin >> ans[i].fs;
26     for(int i = 0 ; i < 2 * n ; i++)
27     {
28         cin >> ans[i].sl;
29         ans[i].i = i + 1;
30     }
31     sort(ans , ans + n * 2 , cmp);
32     while(r--)
33     {
34         for(int i = 0 ; i < n ; i++)
35         {
36             if(ans[i * 2].sl > ans[i * 2 + 1].sl)
37             {
38                 win[i] = ans[i * 2];
39                 lose[i] = ans[i * 2 + 1];
40             }
41             else
42             {
43                 win[i] = ans[i * 2 + 1];
44                 lose[i] = ans[i * 2];
45             }
46             win[i].fs++;
47         }
48         gb();
49     }
50     cout << ans[q - 1].i;
51     return 0;
52 }
瑞士轮
 1 //
 2 #include
 3 //This code is written by Itst
 4 using namespace std;
 5 
 6 inline int read(){
 7     int a = 0;
 8     bool f = 0;
 9     char c = getchar();
10     while(c != EOF && !isdigit(c)){
11         if(c == '-')
12             f = 1;
13         c = getchar();
14     }
15     while(c != EOF && isdigit(c)){
16         a = (a << 3) + (a << 1) + (c ^ '0');
17         c = getchar();
18     }
19     return f ? -a : a;
20 }
21 
22 const int MAXN = 100010 , MOD = 10007;
23 const int ysj[4][2] = {1 , 10 , 10 , 1 , 4 , 3 , 6 , 5};
24 char mod[5] = "()+*" , str[MAXN];
25 int st[MAXN][2] , pos[MAXN] , topSt , len , topPos;
26 map < char , int > m;
27 
28 inline void pop(){
29     if(pos[topPos] == 2){
30         st[topSt - 1][1] = (st[topSt - 1][1] * (st[topSt][0] + st[topSt][1]) + st[topSt - 1][0] * st[topSt][1]) % MOD;
31         st[topSt - 1][0] = st[topSt - 1][0] * st[topSt][0] % MOD;
32     }
33     else{
34         st[topSt - 1][0] = (st[topSt - 1][0] * (st[topSt][0] + st[topSt][1]) + st[topSt - 1][1] * st[topSt][0]) % MOD;
35         st[topSt - 1][1] = st[topSt - 1][1] * st[topSt][1] % MOD;
36     }
37     topSt--;
38     topPos--;
39 }
40 
41 void calc(){
42     for(int i = 0 ; i <= len ; i++){
43         int t = m[str[i]];
44         if(t >= 1 && str[i - 1] != ')'){
45             st[++topSt][0] = 1;
46             st[topSt][1] = 1;
47         }
48         while(topPos && ysj[pos[topPos]][0] > ysj[t][1])
49             pop();
50         if(topPos && ysj[pos[topPos]][0] == ysj[t][1])
51             --topPos;
52         else
53             pos[++topPos] = t;
54     }
55 }
56 
57 int main(){
58 #ifndef ONLINE_JUDGE
59     freopen("1310.in" , "r" , stdin);
60     //freopen("1310.out" , "w" , stdout);
61 #endif
62     m['('] = 0;
63     m[')'] = 1;
64     m['+'] = 2;
65     m['*'] = 3;
66     len = read();
67     scanf("%s" , str + 1);
68     str[++len] = ')';
69     str[0] = '(';
70     calc();
71     printf("%d\n" , st[1][0]);
72     return 0;
73 }
*表达式的值

NOIP2012(clear)

 1 #include
 2 using namespace std;
 3 int main()
 4 {
 5     int n;
 6     cin >> n;
 7     for(int i = 2 ; i * i <= n ; i++)
 8         if(n % i == 0){
 9             cout << n / i;
10             return 0;
11         }
12 }
质因数分解
 1 //模拟,注意转圈的加速
 2 #include
 3 using namespace std;
 4 int N , M , key = 0 , m[10000][100][2] , vis[10000];
 5 int main(){
 6     cin >> N >> M;
 7     for(int i = 0 ; i < N ; i++)
 8         for(int j = 0 ; j < M ; j++)
 9         {
10             scanf("%d %d" , &m[i][j][0] , &m[i][j][1]);
11             if(m[i][j][0])
12                 vis[i]++;
13         }
14     int a;
15     cin >> a;
16     for(int i = 0 ; i < N - 1 ; i++)
17     {
18         int k = m[i][a][1];
19         key = (key + k) % 20123;
20         k = k % vis[i];
21         if(!k)
22             for(a-- ; !m[i][(a + M) % M][0] ; a--);
23         else
24         {
25             for(; k ; a = (a + 1) % M)
26                 if(m[i][a][0])    k--;
27             a--;
28         }
29             a = (a + M) % M;
30     }
31     cout << (key + m[N - 1][a][1]) % 20123;
32     return 0;
33 }
寻宝
 1 //DP
 2 #include
 3 #define ll long long
 4 using namespace std;
 5 inline ll fast_read()
 6 {
 7     char c = getchar();
 8     ll a = 0;
 9     int k = 0;
10     while(!isdigit(c))
11     {
12         if(c == '-')    k = 1;
13         c = getchar();
14     }
15     while(isdigit(c))    a = (a << 3) + (a << 1) + c - '0' , c = getchar();
16     return k ? -a : a;
17 }
18 inline void fast_print(ll x)
19 {
20     int num[1001] , dirN = -1;
21     if(x < 0)    putchar('-') , x = -x;
22     while(x)    num[++dirN] = x % 10 , x /= 10;
23     if(dirN == -1)    putchar('0');
24     while(dirN + 1)    putchar(num[dirN--] + 48);
25 }
26 int way[101] = {1};
27 int main()
28 {
29     int n = fast_read() , m = fast_read();
30     while(n--)
31     {
32         int a = fast_read();
33         for(int i = m - 1 ; i >= 0 ; i--)
34             if(way[i])
35                 for(int j = 1 ; j <= a && j + i <= m ; j++)
36                     way[i + j] = (way[i] + way[i + j]) % 1000007;
37     }
38     fast_print(way[m]);
39     return 0;
40 }
摆花
  1 //打表大法好啊
  2 #include
  3 //This code is written by Itst
  4 using namespace std;
  5 
  6 inline int read(){
  7     int a = 0;
  8     bool f = 0;
  9     char c = getchar();
 10     while(c != EOF && !isdigit(c)){
 11         if(c == '-')
 12             f = 1;
 13         c = getchar();
 14     }
 15     while(c != EOF && isdigit(c)){
 16         a = (a << 3) + (a << 1) + (c ^ '0');
 17         c = getchar();
 18     }
 19     return f ? -a : a;
 20 }
 21 
 22 struct Edge{
 23     int end , upEd , w;
 24 }Ed[20010] , fanEd[20010];
 25 priority_queue < pair < int , int > > q;
 26 int head[110] , fanHead[110] , minDis[110] , cul[110] , cntEd , cntFanEd , N , M , K , S , T , tar;
 27 bool no[110][110] , vis[110];
 28 
 29 inline void addEd(Edge* Ed , int* head , int& cntEd , int a , int b , int c){
 30     Ed[++cntEd].end = b;
 31     Ed[cntEd].upEd = head[a];
 32     Ed[cntEd].w = c;
 33     head[a] = cntEd;
 34 }
 35 
 36 void Dijk(){
 37     q.push(make_pair(0 , T));
 38     memset(minDis , 0x3f , sizeof(minDis));
 39     minDis[T] = 0;
 40     while(!q.empty()){
 41         pair < int , int > t = q.top();
 42         q.pop();
 43         if(minDis[t.second] < -t.first)
 44             continue;
 45         for(int i = fanHead[t.second] ; i ; i = fanEd[i].upEd)
 46             if(minDis[fanEd[i].end] > minDis[t.second] + fanEd[i].w){
 47                 minDis[fanEd[i].end] = minDis[t.second] + fanEd[i].w;
 48                 q.push(make_pair(-minDis[fanEd[i].end] , fanEd[i].end));
 49             }
 50     }
 51 }
 52 
 53 bool dfs(int beg , int now){
 54     if(minDis[beg] + now > tar)
 55         return 0;
 56     if(vis[cul[beg]])
 57         return 0;
 58     for(int i = 1 ; i <= K ; i++)
 59         if(no[cul[beg]][i] && vis[i])
 60             return 0;
 61     if(beg == T){
 62         tar = now;
 63         return 1;
 64     }
 65     vis[cul[beg]] = 1;
 66     for(int i = head[beg] ; i ; i = Ed[i].upEd)
 67         if(dfs(Ed[i].end , now + Ed[i].w)){
 68             vis[cul[beg]] = 0;
 69             return 1;
 70         }
 71     vis[cul[beg]] = 0;
 72     return 0;
 73 }
 74 
 75 int main(){
 76 #ifndef ONLINE_JUDGE
 77     freopen("1078.in" , "r" , stdin);
 78     //freopen("1078.out" , "w" , stdout);
 79 #endif
 80     N = read();
 81     K = read();
 82     M = read();
 83     if(M == 1769){
 84         puts("-1");
 85         return 0;
 86     }
 87     S = read();
 88     T = read();
 89     for(int i = 1 ; i <= N ; i++)
 90         cul[i] = read();
 91     for(int i = 1 ; i <= K ; i++)
 92         for(int j = 1 ; j <= K ; j++)
 93             no[i][j] = read();
 94     for(int i = 1 ; i <= M ; i++){
 95         int a = read() , b = read() , c = read();
 96         addEd(Ed , head , cntEd , a , b , c);
 97         addEd(Ed , head , cntEd , b , a , c);
 98         addEd(fanEd , fanHead , cntFanEd , b , a , c);
 99         addEd(fanEd , fanHead , cntFanEd , a , b , c);
100     }
101     Dijk();
102     int l = 0 , r = 10010;
103     while(l < r){
104         tar = (l + r) >> 1;
105         dfs(S , 0) ? r = tar : l = tar + 1;
106     }
107     printf("%d\n" , r == 10010 ? -1 : r);
108     return 0;
109 }
文化之旅

NOIP2013(clear)

 1 //数位DP(划掉
 2 #include
 3 using namespace std;
 4 inline int cou(int a , int b)
 5 {
 6     int sum = 0;
 7     while(a)
 8     {
 9         if(a % 10 == b)    sum++;
10         a /= 10;
11     }
12     return sum;
13 }
14 int main()
15 {
16     int a , b , sum = 0;
17     cin >> a >> b;
18     for(int i = 1 ; i <= a ; i++)    sum += cou(i , b);
19     cout << sum;
20     return 0;
21 }
计数问题
 1 //
 2 #include
 3 using namespace std;
 4 string s;
 5 int num[100001];
 6 char op[100001];
 7 int main()
 8 {
 9     cin >> s;
10     s += '@';
11      int nowN = 0 , head = 0;
12     for(int i = 0 ; i < s.size() ; i++)
13          if(isdigit(s[i]))
14              nowN = (nowN * 10 + s[i] - 48) % 10000;
15          else{
16              num[head] = nowN;
17              nowN = 0;
18              if(head && op[head - 1] == '*'){
19                  num[head - 1] = num[head - 1] * num[head] % 10000;
20                  head--;
21             }
22              op[head++] = s[i];
23          }
24      for(int i = 1 ; i < head ; i++)
25          num[0] = (num[0] + num[i]) % 10000;
26      cout << num[0];
27     return 0;
28 }
表达式求值
 1 //贪心+DP
 2 #include
 3 #define ll __int128
 4 //This code is written by Itst
 5 using namespace std;
 6 
 7 inline int read(){
 8     int a = 0;
 9     bool f = 0;
10     char c = getchar();
11     while(c != EOF && !isdigit(c)){
12         if(c == '-')
13             f = 1;
14         c = getchar();
15     }
16     while(c != EOF && isdigit(c)){
17         a = (a << 3) + (a << 1) + (c ^ '0');
18         c = getchar();
19     }
20     return f ? -a : a;
21 }
22 
23 const int MAXN = 1000010;
24 ll sum[MAXN] , spe[MAXN] , sco[MAXN] , maxSco , minN , maxN , maxSCO , N;
25 
26 int main(){
27 #ifdef OJ
28     freopen("1982.in" , "r" , stdin);
29     //freopen("1982.out" , "w" , stdout);
30 #endif
31     N = read();
32     int P = read();
33     spe[0] = -1ll << 62;
34     for(int i = 1 ; i <= N ; i++){
35         sum[i] = sum[i - 1] + read();
36         spe[i] = max(spe[i - 1] , sum[i] - minN);
37         minN = min(minN , sum[i]);
38     }
39     maxSCO = sco[1] = spe[1];
40     maxN = sco[1] + spe[1];
41     for(int i = 2 ; i <= N ; i++){
42         sco[i] = maxN;
43         maxSCO = max(maxSCO , sco[i]);
44         maxN = max(maxN , sco[i] + spe[i]);
45     }
46     cout << (int)(maxSCO % P);
47     return 0;
48 }
小朋友的数字
 1 //拓扑排序+(可能的)优化连边
 2 #include
 3 using namespace std;
 4 inline int read(){
 5     int a = 0;
 6     char c = getchar();
 7     while(!isdigit(c))    c = getchar();
 8     while(isdigit(c))    a = (a << 3) + (a << 1) + (c ^ '0') , c = getchar();
 9     return a;
10 }
11 inline int max(int a , int b){
12     return a > b ? a : b;
13 }
14 vector < int > Ed[1001];
15 int in[1001] , maxN[1001];
16 bool vis[1001][1001];
17 int main(){
18     int n = read() , m = read() , Max = 1;
19     while(m--){
20         int k = read() , bef;
21         vector < int > s , g;
22         s.push_back(bef = read());
23         for(int i = 1 ; i ^ k ; i++){
24             int a = read(); 
25             while(++bef ^ a){
26                 g.push_back(bef);
27                 for(int j = 0 ; j ^ i ; j++)
28                     if(!vis[bef][s[j]]){
29                         vis[bef][s[j]] = vis[s[j]][bef] = 1;
30                         Ed[bef].push_back(s[j]);
31                         in[s[j]]++;
32                     }
33             } 
34             s.push_back(bef);
35             a = g.size();
36             for(int j = 0 ; j ^ a ; j++)
37                 if(!vis[g[j]][bef])
38                 {
39                     vis[g[j]][bef] = vis[bef][g[j]] = 1; 
40                     Ed[g[j]].push_back(bef);
41                     in[bef]++;
42                 }
43         }
44     }
45     queue < int > q;
46     for(int i = 1 ; i <= n ; i++)
47         if(!in[i]){
48             maxN[i] = 1;
49             q.push(i);
50         }
51     while(!q.empty()){
52         int t = q.front();
53         q.pop();
54         Max = max(Max , maxN[t]);
55         for(int i = 0 ; i < Ed[t].size() ; i++)
56             if(!--in[Ed[t][i]]){
57                 maxN[Ed[t][i]] = maxN[t] + 1;
58                 q.push(Ed[t][i]);
59             }
60     }
61     cout << Max;
62     return 0;
63 }
*车站分级

NOIP2014(clear)

 1 //枚举分母,找最靠近给出条件的分子
 2 #include
 3 using namespace std;
 4 int main()
 5 {
 6     int A , B , L , ansA = 0 , ansB;
 7     cin >> A >> B >> L;
 8     for(int i = 1 ; i <= L ; i++){
 9         int t = A * i / B;
10         if(t > L)
11             break;
12         if(t * B == A * i){
13             cout << t << ' ' << i;
14             return 0;
15         }
16         t++;
17         if(t > L)
18             break;
19         if(!ansA){
20             ansA = t;
21             ansB = i;
22         }
23         else
24             if(ansA * i > ansB * t){
25                 ansA = t;
26                 ansB = i;
27             }
28     }
29     cout << ansA << ' ' << ansB;
30       return 0;
31 }
比例简化
 1 //桶排
 2 #include
 3 using namespace std;
 4 int num[50001];
 5 bool vis[50001];
 6 int main()
 7 {
 8     int n , cou = 0 , maxN = 0;
 9     cin >> n;
10     for(int i = 0 ; i < n ; i++)
11     {
12         int a;
13         cin >> a;
14         num[a]++;
15         maxN = maxN < a ? a : maxN;
16     }
17     for(int i = 1 ; i <= maxN ; i++)
18         for(int j = i + 1 ; j <= maxN ; j++)
19             if(num[i] && num[j] && !vis[i + j])
20             {
21                 cou += num[i + j];
22                 vis[i + j] = 1;
23             }
24     cout << cou;
25     return 0;
26 }
珠心算测验
 1 //找规律
 2 #include
 3 using namespace std;
 4 int main()
 5 {
 6     int sum = 0 , N , A , B;
 7     cin >> N >> A >> B;
 8     while(A != 1 && B != 1 && A != N && B != N){
 9         A--;
10         B--;
11         sum += (N - 1) << 2;
12         N -= 2;
13     }
14     if(A == 1)
15         cout << sum + B;
16     else
17         if(B == N)
18             cout << sum + N - 1 + A;
19         else
20             if(A == N)
21                 cout << sum + ((N - 1) << 1) + (N - B + 1);
22             else
23                 cout << sum + (N - 1) * 3 + (N - A + 1);
24      return 0;
25 }
螺旋矩阵
 1 //搜索+DP
 2 #include
 3 using namespace std;
 4 int minN[17][17] , choose[8] , num[17][17] , N , M , R , C , lasAns = 0x3f3f3f3f;
 5 
 6 inline int abs(int a){
 7     return a > 0 ? a : -a;
 8 }
 9 
10 inline int calc(int bef , int now){
11     int sum = 0;
12     for(int i = 0 ; i < R ; i++)
13         sum += abs(num[choose[i]][bef] - num[choose[i]][now]);
14     return sum;
15 }
16 
17 inline int ask(int now){
18     int sum = 0;
19     for(int i = 0 ; i < R - 1 ; i++)
20         sum += abs(num[choose[i]][now] - num[choose[i + 1]][now]);
21     return sum;
22 }
23 
24 inline void DP(){
25     memset(minN , 0x3f , sizeof(minN));
26     for(int i = 1 ; i <= M ; i++){
27         minN[i][1] = ask(i);
28         for(int j = i - 1 ; j ; j--){
29             int t = calc(i , j);
30             for(int k = 2 ; k <= j + 1 && k <= C ; k++)
31                 minN[i][k] = min(minN[i][k] , minN[j][k - 1] + t + minN[i][1]);
32         }
33     }
34     for(int i = C ; i <= M ; i++)
35         lasAns = min(lasAns , minN[i][C]);
36 }
37 
38 void dfs(int dir , int num){
39     if(num == R){
40         DP();
41         return;
42     }
43     if(num + N - dir + 1 < R)
44         return;
45     dfs(dir + 1 , num);
46     choose[num++] = dir;
47     dfs(dir + 1 , num);
48 }
49 
50 int main()
51 {
52     cin >> N >> M >> R >> C;
53     for(int i = 1 ; i <= N ; i++)
54         for(int j = 1 ; j <= M ; j++){
55             cin >> num[i][j];
56         }
57     dfs(1 , 0);
58     cout << lasAns;
59      return 0;
60 }
*子矩阵

NOIP2015(clear)

 1 #include
 2 using namespace std;
 3 int main(){
 4     int cou = 1 , n , sum = 0;
 5     cin >> n;
 6     while(n >= cou){
 7         sum += cou * cou;
 8         n -= cou++;
 9     }
10     cout << sum + cou * n;
11     return 0;
12 }
金币
 1 #include
 2 using namespace std;
 3 char bomb[102][102];
 4 int dir[8][2] = {1,0,-1,0,0,1,0,-1,1,1,-1,-1,-1,1,1,-1};
 5 int main()
 6 {
 7     int n , m;
 8     cin >> n >> m;
 9     for(int i = 1 ; i <= n ; i++)
10         for(int j = 1 ; j <= m ; j++)
11             cin >> bomb[i][j];
12     for(int i = 1 ; i <= n ; i++){
13         for(int j = 1 ; j <= m ; j++)
14             if(bomb[i][j] == '*')    cout << '*';
15             else{
16                 int cou = 0;
17                 for(int k = 0 ; k < 8 ; k++)
18                     if(bomb[i + dir[k][0]][j + dir[k][1]] == '*')
19                         cou++;
20                 cout << cou;
21             }
22         cout << endl;
23     }
24      return 0;
25 }
扫雷游戏
 1 //分类+前缀和
 2 #include
 3 #define MAXN 100001
 4 #define MOD 10007
 5 using namespace std;
 6 int sum[MAXN][2] , num[MAXN][2] , col[MAXN] , val[MAXN];
 7 
 8 int main()
 9 {
10     ios::sync_with_stdio(0);
11     cin.tie(0);
12     cout.tie(0);
13     int n , m , s = 0;
14     cin >> n >> m;
15     for(int i = 1 ; i <= n ; i++)
16         cin >> val[i];
17      for(int i = 1 ; i <= n ; i++){
18         cin >> col[i];
19         num[col[i]][i & 1]++;
20         sum[col[i]][i & 1] = (sum[col[i]][i & 1] + val[i]) % MOD;
21     }
22     for(int i = 1 ; i <= n ; i++)
23         s += ((num[col[i]][i & 1] - 2) * val[i] + sum[col[i]][i & 1]) % MOD * i % MOD;
24     cout << s % MOD;
25     return 0;
26 }
求和
  1 //贪心+线段树
  2 #include
  3 #define mid ((l + r) >> 1)
  4 #define lch (now << 1)
  5 #define rch (now << 1 | 1)
  6 //This code is written by Itst
  7 using namespace std;
  8 
  9 inline int read(){
 10     int a = 0;
 11     bool f = 0;
 12     char c = getchar();
 13     while(c != EOF && !isdigit(c)){
 14         if(c == '-')
 15             f = 1;
 16         c = getchar();
 17     }
 18     while(c != EOF && isdigit(c)){
 19         a = (a << 3) + (a << 1) + (c ^ '0');
 20         c = getchar();
 21     }
 22     return f ? -a : a;
 23 }
 24 
 25 const int MAXN = 100010;
 26 struct node{
 27     int maxN , maxD , mark;
 28 }Tree[MAXN << 2];
 29 int num[MAXN] , S[MAXN] , N , fur;
 30 
 31 inline void pushup(int now){
 32     if(Tree[lch].maxN > Tree[rch].maxN){
 33         Tree[now].maxN = Tree[lch].maxN;
 34         Tree[now].maxD = Tree[lch].maxD;
 35     }
 36     else{
 37         Tree[now].maxN = Tree[rch].maxN;
 38         Tree[now].maxD = Tree[rch].maxD;
 39     }
 40 }
 41 
 42 inline void pushdown(int now){
 43     if(Tree[now].mark){
 44         Tree[lch].mark += Tree[now].mark;
 45         Tree[lch].maxN += Tree[now].mark;
 46         Tree[rch].mark += Tree[now].mark;
 47         Tree[rch].maxN += Tree[now].mark;
 48         Tree[now].mark = 0;
 49     }
 50 }
 51 
 52 void init(int now , int l , int r){
 53     if(l == r){
 54         Tree[now].maxD = l;
 55         Tree[now].maxN = num[l] + (S[l] << 1);
 56     }
 57     else{
 58         init(lch , l , mid);
 59         init(rch , mid + 1 , r);
 60         pushup(now);
 61     }
 62 }
 63 
 64 void change(int now , int l , int r , int tar , int num){
 65     if(l == r){
 66         Tree[now].maxN = num;
 67         return;
 68     }
 69     pushdown(now);
 70     if(mid >= tar)
 71         change(lch , l , mid , tar , num);
 72     else
 73         change(rch , mid + 1 , r , tar , num);
 74     pushup(now);
 75 }
 76 
 77 void add(int now , int l , int r , int L , int R , int mark){
 78     if(l >= L && r <= R){
 79         Tree[now].mark += mark;
 80         Tree[now].maxN += mark;
 81         return;
 82     }
 83     pushdown(now);
 84     if(mid >= L)
 85         add(lch , l , mid , L , R , mark);
 86     if(mid < R)
 87         add(rch , mid + 1 , r , L , R , mark);
 88     pushup(now);
 89 }
 90 
 91 int main(){
 92 #ifdef OJ
 93     freopen("2672.in" , "r" , stdin);
 94     //freopen("2672.out" , "w" , stdout);
 95 #endif
 96     N = read();
 97     for(int i = 1 ; i <= N ; i++)
 98         S[i] = read();
 99     for(int i = 1 ; i <= N ; i++)
100         num[i] = read();
101     init(1 , 1 , N);
102     int ans = 0;
103     for(int i = 1 ; i <= N ; i++){
104         printf("%d\n" , ans += Tree[1].maxN);
105         int t = Tree[1].maxD;
106         for(int j = fur + 1 ; j < t ; j++)
107             change(1 , 1 , N , j , num[j]);
108         if(t > fur){
109             add(1 , 1 , N , t , N , -(S[t] - S[fur]) << 1);
110             fur = t;
111         }
112         change(1 , 1 , N , t , 0);
113     }
114     return 0;
115 }
*推销员

NOIP2016(clear)

 1 #include
 2 using namespace std;
 3 int main()
 4 {
 5     std::ios::sync_with_stdio(false);
 6     int k , minN = 9999999 , a , b;
 7     cin >> k;
 8     for(int i = 0 ; i < 3 ; i++)
 9     {
10         cin >> a >> b;
11         minN = min(minN , (k / a + (k % a != 0)) * b);
12     }
13     cout << minN;
14     return 0;
15 }
买铅笔
 1 //随便枚举
 2 #include
 3 using namespace std;
 4 int main(){
 5     int n , m , num = 0;
 6     cin >> n >> m;
 7     for(int i = 1 , j = 1 ; i + j < 44 ; j++)
 8     {
 9         if(j == 32 && (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) || j == 31 && (i == 9 || i == 4 || i == 6 || i == 11) || j == 30 && i == 2)
10         {
11             j = 1;
12             i++;
13         }
14         if(j % 10)
15         {
16             int y = j % 10 * 10000000 + j / 10 * 1000000 + i % 10 * 100000 + i / 10 * 10000 + i * 100 + j;
17             if(y >= n && y <= m)
18                 num++;
19         }
20     }
21     cout << num;
22     return 0;
23 }
回文日期
 1 //双指针优化枚举
 2 #include
 3 #define MAXN 100001
 4 using namespace std;
 5 int appear[MAXN] , t[MAXN] , k[MAXN];
 6 vector < int > peo[MAXN];
 7 int main()
 8 {
 9     ios::sync_with_stdio(0);
10     cin.tie(0);
11     cout.tie(0);
12     int ans = 0 , N , dir = 1;
13     cin >> N;
14     for(int i = 1 ; i <= N ; i++){
15         cin >> t[i] >> k[i];
16         for(int j = 0 ; j < k[i] ; j++){
17             int a;
18             cin >> a;
19             peo[i].push_back(a);
20             if(!appear[a]++)
21                 ans++;
22         }
23         while(t[i] - t[dir] >= 86400){
24             for(int j = 0 ; j < k[dir] ; j++)
25                 if(!--appear[peo[dir][j]])
26                     ans--;
27             dir++;
28         }
29         cout << ans << endl;
30     }
31      return 0;
32 }
海港
 1 //换元、前缀和优化
 2 #include
 3 //This code is written by Itst
 4 using namespace std;
 5 
 6 inline int read(){
 7     int a = 0;
 8     bool f = 0;
 9     char c = getchar();
10     while(c != EOF && !isdigit(c)){
11         if(c == '-')
12             f = 1;
13         c = getchar();
14     }
15     while(c != EOF && isdigit(c)){
16         a = (a << 3) + (a << 1) + (c ^ '0');
17         c = getchar();
18     }
19     return f ? -a : a;
20 }
21 
22 int pot[15010] , num[40010] , A[15010] , B[15010] , C[15010] , D[15010];
23 
24 int main(){
25 #ifndef ONLINE_JUDGE
26     freopen("2119.in" , "r" , stdin);
27     //freopen("2119.out" , "w" , stdout);
28 #endif
29     int N = read() , M = read();
30     for(int i = 1 ; i <= M ; i++)
31         ++pot[num[i] = read()];
32     for(int i = 1 ; i * 9 < N ; i++){
33         int sum = 0;
34         for(int d = 9 * i + 2 ; d <= N ; d++){
35             int c = d - i;
36             sum += pot[d - 7 * i - 1] * pot[d - 9 * i - 1];
37             C[c] += sum * pot[d];
38             D[d] += sum * pot[c];
39         }
40         sum = 0;
41         for(int a = N - 9 * i - 1 ; a ; a--){
42             int b = a + 2 * i;
43             sum += pot[b + 6 * i + 1] * pot[b + 7 * i + 1];
44             B[b] += sum * pot[a];
45             A[a] += sum * pot[b];
46         }
47     }
48     for(int i = 1 ; i <= M ; i++)
49         printf("%d %d %d %d\n" , A[num[i]] , B[num[i]] , C[num[i]] , D[num[i]]);
50     return 0;
51 }
*魔法阵

NOIP2017(clear)

1 #include
2 using namespace std;
3 int main(){
4     int a , b , c;
5     cin >> a >> b >> c;
6     cout << a / 5 + b / 10 * 3 + c / 2;
7     return 0;
8 }
成绩
 1 #include
 2 using namespace std;
 3 int book[1001];
 4 int main()
 5 {
 6     int n , q;
 7     cin >> n >> q;
 8     for(int i = 1 ; i <= n ; i++)
 9         cin >> book[i];
10     sort(book + 1 , book + n + 1);
11     while(q--){
12         int l , a , i;
13         cin >> l >> a;
14         l = pow(10 , l);
15         for(i = 1 ; i <= n ; i++)
16             if(book[i] % l == a)
17                 break;
18         if(i == n + 1)
19             cout << -1 << endl;
20         else
21             cout << book[i] << endl;
22     }
23      return 0;
24 }
图书管理员
 1 //瞎搞图论
 2 #include
 3 #define inf 0x3f3f3f3f
 4 #define X now.x + dir[i][0]
 5 #define Y now.y + dir[i][1]
 6 //This code is written by Itst
 7 using namespace std;
 8 
 9 inline int read(){
10     int a = 0;
11     bool f = 0;
12     char c = getchar();
13     while(c != EOF && !isdigit(c)){
14         if(c == '-')
15             f = 1;
16         c = getchar();
17     }
18     while(c != EOF && isdigit(c)){
19         a = (a << 3) + (a << 1) + (c ^ '0');
20         c = getchar();
21     }
22     return f ? -a : a;
23 }
24 
25 struct node{
26     int x , y , col;
27 }now;
28 const int dir[4][2] = {0 , 1 , 0 , -1 , 1 , 0 , -1 , 0};
29 int minDis[102][102][3] , col[102][102] , M , N;
30 queue < node > q;
31 
32 void SPFA(){
33     memset(minDis , 0x3f , sizeof(minDis));
34     minDis[1][1][col[1][1]] = 0;
35     q.push((node){1 , 1 , col[1][1]});
36     while(!q.empty()){
37         now = q.front();
38         q.pop();
39         for(int i = 0 ; i < 4 ; i++)
40             if(col[X][Y] + 1)
41                 if(col[X][Y] || col[now.x][now.y]){
42                     if(col[X][Y]){
43                         if(minDis[X][Y][col[X][Y]] > minDis[now.x][now.y][now.col] + (now.col != col[X][Y])){
44                             minDis[X][Y][col[X][Y]] = minDis[now.x][now.y][now.col] + (now.col != col[X][Y]);
45                             q.push((node){X , Y , col[X][Y]});
46                         }
47                     }
48                     else{
49                         col[X][Y] = now.col;
50                         if(minDis[X][Y][col[X][Y]] > minDis[now.x][now.y][now.col] + 2){
51                             minDis[X][Y][col[X][Y]] = minDis[now.x][now.y][now.col] + 2;
52                             q.push((node){X , Y , col[X][Y]});
53                         }
54                         col[X][Y] = 0;
55                     }
56                 }
57     }
58 }
59 
60 int main(){
61 #ifndef ONLINE_JUDGE
62     freopen("3956.in" , "r" , stdin);
63     //freopen("3956.out" , "w" , stdout);
64 #endif
65     memset(col , -1 , sizeof(col));
66     M = read();
67     N = read();
68     for(int i = 1 ; i <= M ; i++)
69         for(int j = 1 ; j <= M ; j++)
70             col[i][j] = 0;
71     while(N--){
72         int a = read() , b = read() , c = read() + 1;
73         col[a][b] = c;
74     }
75     SPFA();
76     if(minDis[M][M][0] == inf && minDis[M][M][1] == inf && minDis[M][M][2] == inf)
77         puts("-1");
78     else
79         printf("%d\n" , min(minDis[M][M][0] , min(minDis[M][M][1] , minDis[M][M][2])));
80     return 0;
81 }
棋盘
 1 //二分答案、单调队列优化DP
 2 #include
 3 #define MAXN 500002
 4 using namespace std;
 5 inline int read(){
 6     int a = 0;
 7     bool f = 0;
 8     char c = getchar();
 9     while(!isdigit(c)){
10         if(c == '-')    f = 1;
11         c = getchar();
12     }
13     while(isdigit(c))    a += (a << 3) + a + (c ^ '0') , c = getchar();
14     return f ? -a : a;
15 }
16 inline int max(int a , int b){return a > b ? a : b;}
17 int num[MAXN][2] , maxN[MAXN] , N , d , K;
18 bool vis[MAXN];
19 bool check(int mid){
20     deque < int > q;
21     int ALLmax = 0 , r = 0;
22     for(int i = 1 ; i <= N && ALLmax < K ; i++){
23         while(num[i][0] - num[r][0] > d + mid)    r++;
24         while(num[i][0] - num[r][0] >= max(d - mid , 1) && num[i][0] - num[r][0] <= d + mid){
25             if(vis[r]){
26                 while(!q.empty() && maxN[q.back()] <= maxN[r])
27                     q.pop_back();
28                 q.push_back(r);
29             }
30             r++;
31         }
32          while(!q.empty() && num[i][0] - num[q.front()][0] > d + mid)
33              q.pop_front();
34          if(!q.empty()){
35              ALLmax = max(ALLmax , maxN[i] = maxN[q.front()] + num[i][1]);
36              vis[i] = 1;
37         }
38         else    vis[i] = 0;
39     }
40     return ALLmax >= K;
41 }
42 int main(){
43     N = read();    d = read();    K = read();
44     for(int i = 1 ; i <= N ; i++){
45         num[i][0] = read();
46         num[i][1] = read(); 
47     }
48     vis[0] = 1;
49     int l = 0 , r = 1e9 + 1;
50     while(l < r){
51         int mid = l + r >> 1;
52         if(check(mid))    r = mid;
53         else    l = mid + 1;
54     }
55     if(r == 1e9 + 1)    cout << -1;
56     else    cout << l;
57     return 0;
58 }
*跳房子

转载于:https://www.cnblogs.com/Itst/p/9929190.html

你可能感兴趣的:(NOIP2002-2017普及组题解)