UCF Local Programming Contest 2016

比赛链接

E题 解题思路:


模拟题(最近写模拟写多了,真的感觉恶心了)

首先我们将矩阵中的首字母的位置标记好(便于直接找首字母),然后我们找单词时,直接找他的首字母,然后按照上下左右四个方向找(最近总是不敢暴力,总是感觉超时,结果没啥事,时间复杂度得好好算算),然后对于向上和向下找,我们开始赋值都是(2 *n - 1 或者 2 * m - 1,因为这样不会成负值),然后向下后者向右直接 + 1取模就OK。

注意:变量别整混了,然后x, y 看好,学到了typedef struct 结构体
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

typedef struct solve{
    int x, y;
}N;

char g[30][30];

vector <N> ans[30];

int main(){
    int t ;
    scanf("%d",&t);
    for (int k = 1; k <= t; k ++){
        printf("Word search puzzle #%d:\n",k);
        for (int i = 0; i < 26; i ++){
            ans[i].clear();
        }
        int n, m;
        scanf("%d%d",&n,&m);
        for (int i = 0 ; i < n; i++){
            scanf("%s",g[i]);
            for (int j = 0; j < m; j ++){
                N temp;
                temp.x = i, temp.y = j;
                ans[g[i][j] - 'A'].push_back(temp);
            }
        }
        int l;
        scanf("%d",&l);
        for (int i = 0; i < l; i ++){
            string st;
            cin>>st;
            int j = 0;
            int p = st.length();
            for (int i = 0; i < ans[st[0] - 'A'].size(); i++){
                // 上下左右四个方向

                // 上:
                int q = 1;
                int f = 1;
                for (int w = (ans[st[0] - 'A'][i].x + 2 * n - 1) % n ; f < p; f ++ ,w = (w + 2 * n - 1) % n){
                    if (st[f] != g[w][ans[st[0] - 'A'][i].y]){
                        q = 0;
                        break;
                    }
                }
                if (q){
                    printf("U %d %d ",ans[st[0] - 'A'][i].x + 1,ans[st[0] - 'A'][i].y + 1);
                    cout << st <<endl;
                    break;
                }

                // 下
                q = 1;
                f = 1;
                for (int w = (ans[st[0] - 'A'][i].x + 1) % n ; f < p; f ++ ,w = (w + 1) % n){
                    if (st[f] != g[w][ans[st[0] - 'A'][i].y]){
                        q = 0;
                        break;
                    }
                }
                if (q){
                    printf("D %d %d ",ans[st[0] - 'A'][i].x + 1,ans[st[0] - 'A'][i].y + 1);
                    cout << st <<endl;
                    break;
                }

                // 左

                q = 1;
                f = 1;
                for (int w = (ans[st[0] - 'A'][i].y + 2 * m - 1) % m ; f < p; f ++ ,w = (w + 2 * m - 1) % m){
                    if (st[f] != g[ans[st[0] - 'A'][i].x][w]){
                        q = 0;
                        break;
                    }
                }
                if (q){
                    printf("L %d %d ",ans[st[0] - 'A'][i].x + 1,ans[st[0] - 'A'][i].y + 1);
                    cout << st <<endl;
                    break;
                }

                // 右
                q = 1;
                f = 1;
                for (int w = (ans[st[0] - 'A'][i].y +  1) % m ; f < p; f ++ ,w = (w +  1) % m){
                    if (st[f] != g[ans[st[0] - 'A'][i].x][w]){
                        q = 0;
                        break;
                    }
                }
                if (q){
                    printf("R %d %d ",ans[st[0] - 'A'][i].x + 1,ans[st[0] - 'A'][i].y + 1);
                    cout << st <<endl;
                    break;
                }
            }
        }
        printf("\n");
    }
    return 0;
}


F题 解题思路:


计算几何,好讨厌精度问题

这个计算几何挺简单的,我们只要枚举每2个点,然后去求出有没有另一个点是他的中点,然后再去求另一个点,他与另外两个点的距离相同,并且他与中点的距离等于另外两个点的距离。

注意:一开始忽略了精度的问题,直接map存的点是否存在,导致精度的误差,所以wa了,这里不用判断垂直,因为这些条件就可以说明他是垂直的,可以自己推一下
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>

using namespace std;

typedef long long ll;

const int N = 1010;

map <double, map<double,int> > vis;
double a[N], b[N];


bool check(double x, double y, int n){
    for (int i = 0; i < n; i++){
        if (fabs(x - a[i]) <= 0.0000001 && fabs( y - b[i]) <= 0.0000001) return true;
    }    
    return false;
}

int main(){
    int t;
    scanf("%d",&t);
    for (int k = 1; k <= t; k++){
        int n;
        scanf("%d",&n);
        vis.clear();
        for (int i = 0; i < n; i++){
            scanf("%lf%lf",&a[i],&b[i]);
            vis[a[i]][b[i]] = 1;
        }
        ll res = 0;
        for (int i = 0; i < n; i++){
            for (int j = i + 1; j < n; j++){
                double x = (a[i] + a[j]) / 2;
                double y = (b[i] + b[j]) / 2;
                if (check(x,y,n)){
                    for (int l = 0; l < n; l ++){
                        double xx = sqrt(fabs(a[l] - a[i]) * fabs(a[l] - a[i]) + fabs(b[l] - b[i]) * fabs(b[l] - b[i]));
                        double yy = sqrt(fabs(a[l] - a[j]) * fabs(a[l] - a[j]) + fabs(b[l] - b[j]) * fabs(b[l] - b[j]));
                        double x1 = sqrt((a[j] - a[i]) * (a[j] - a[i]) + (b[j] - b[i]) * (b[j] - b[i]));
                    	double x2 = sqrt((a[l] - x) * (a[l] - x) + (b[l] - y) * (b[l] - y));
                    	if (fabs(x1 - x2) <= 0.0000001 && fabs(xx - yy) <= 0.0000001) res ++;
                    }
                }
            }
        }
        printf("Set #%d: %lld\n\n",k,res);
    }
    return 0;
}


H题 解题思路:


挺喜欢这种题,竟然忘记了筛法,哭了

问存在多少组能被整除的(本身除外),首先我们考虑0 和 1, 0的话 0/ 除 0 外的数都可以,所以是 a[0] * (n - a[0]),然后 1 的为a[1] *(n - a[0] - a[1]),然后对于其他的我们双重for循环,然后我们利用筛法 j = i + i ; j < n; j += i。

注意longlong

代码:
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

typedef long long ll;

const int N = 10000010;

int a[N];

int main(){
    int t;
    scanf("%d",&t);
    for (int k = 1; k <= t; k++){
        int n;
        scanf("%d",&n);
        memset(a,0,sizeof a);
        int mx = 0;
        for (int i = 0; i < n ;i ++){
            int x;
            scanf("%d",&x);
            a[x]++;
            mx = max(x, mx);
        }
        ll res = (ll)a[0] * (n - a[0]) + (ll)a[1] * (n - a[1] - a[0]);
        for (int i = 2; i <= mx/2; i ++){
            if (a[i]){
                for (int j = i + i; j <= mx; j += i){
                    if (a[j]) res += (ll)a[j] * (ll)a[i];
                }
            }
            
        }
        printf("Test case #%d: %lld\n\n",k,res);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值