usco题解

博主分享了参与USASO的经历,尽管认为过程有些枯燥,但认识到提升代码能力的重要性。文章详细探讨了Chapter 1中1.2.1题的解法,包括使用线段树和排序扫描的方法,并提到了处理输入输出的技巧,如使用ifstream和ofstream。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

老师特别执着地让我做USASO那好吧。。我尽快把它做完! 虽然大家都说做这个蛮无聊的, 但我的代码能力有提升的必要, 现在的代码能力太烂啦!

Chapter 1

1.2

1.2.1: 这道题的解法还是很多的! 我为了练习先打了一个线段树, 但是这道题还必须离散一下要不然会爆空间。。最后写出来巨丑就不发了。 然后又写了一个简单的排序之后扫一遍的方法。

/*
ID: ayaya1
LANG: C++
TASK: milk2
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int n, ans1, ans2;
struct point{
    int l, r;    
}a[5005];
bool cmp(point x, point y){
    return x.l < y.l;    
}
int main()
{
    freopen("milk2.in", "r", stdin);
    freopen("milk2.out", "w", stdout);
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)scanf("%d%d", &a[i].l, &a[i].r);
    sort(a + 1, a + n + 1, cmp);
    for(int i = 1; i <= n;){
        int j = i + 1, ts = a[i].l, te = a[i].r;
        while(1){
            if(j > n)break;
            if(a[j].l <= te){
                te = max(te, a[j].r);    
                j ++;
            }    
            else break;
        }
        ans1 = max(ans1,te - ts);
        if(j <= n)ans2 = max(ans2, a[j].l - te);    
        i = j;
    }
    printf("%d %d\n", ans1, ans2);
  //  system("pause");
    return 0;
}
1.2.2

最简单的模拟。。。就是要注意如果多种方式都可以满足的话输出的是最小的那个的序号。

/*
ID: ayaya1
LANG: C++
TASK: transform
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int n;
bool a[12][12], b[12][12];
void zhuan90(){
    int c[12][12];
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n; j ++)
            c[i][j] = a[n + 1 - j][i];     
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n; j ++)
            a[i][j] = c[i][j];
}
bool pd(){
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n ; j ++)
            if(a[i][j] != b[i][j])return 0;
    return 1;    
}
void fan(){
    int c[12][12];
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n; j ++)
            c[i][j] = a[i][n + 1 - j];
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n; j ++)
            a[i][j] = c[i][j];    
}
int main()
{
    freopen("transform.in", "r", stdin);
    freopen("transform.out", "w", stdout);
    scanf("%d", &n);
    char c;
    for(int i = 1; i <= n; i ++){getchar();
        for(int j = 1; j <= n; j ++){
            scanf("%c", &c); if(c == '@')a[i][j] = 1;    
        }
    }
    for(int i = 1; i <= n; i ++){getchar();
        for(int j = 1; j <= n; j ++){
            scanf("%c", &c); if(c == '@')b[i][j] = 1;    
        }
    } 
    
    zhuan90();
    if(pd()){puts("1"); return 0;}
    zhuan90();
    if(pd()){puts("2"); return 0;}
    zhuan90();
    if(pd()){puts("3"); return 0;}
    zhuan90();
    fan();
    if(pd()){puts("4"); return 0;}
    zhuan90();
    if(pd()){puts("5"); return 0;}
    zhuan90();
    if(pd()){puts("5"); return 0;}
    zhuan90();
    if(pd()){puts("5"); return 0;}
    zhuan90();
    if(pd()){puts("6"); return 0;}
    puts("7");
    //system("pause");
    return 0;
}

1.2.3

这道题就是纯考我读入啊。。。不会用fstream的。。

学了一下, 发现还是非常简单好用的。

声明的时候:

ifstream @@@("***.in");

ofstream ###("***.out");

使用的时候:

@@@>>a;

###<<b;

这道题会这个应该就行了

接下来的做法就是每读入一个单词就查询它是否与输入的数匹配就好啦!

/*
ID: ayaya1
LANG: C++
TASK: namenum
*/
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
string a, c, b;
int dui[26] = {2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 0,  7, 7, 8, 8, 8, 9, 9, 9, 0};
int main()
{
    freopen("namenum.in", "r", stdin);
    ifstream tin("dict.txt", ios::in);
    freopen("namenum.out", "w", stdout);
    cin>>a; int lena = a.size();
  //  cout<<a<<endl;
    int flag = 0;
   while(tin>>b){
        int lenb = b.size();
        if(lenb != lena)continue;    
        c = b;
        for(int i = 0; i < lenb; i ++)c[i] = dui[c[i] - 'A'] + '0';
        if(a == c){
            flag = 1; cout<<b<<endl;
        }//cout<<b<<endl;
        if(b[0] == 'Z')break;
    }
    if(!flag)puts("NONE");
  //  system("pause");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值