比赛链接
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;
}
计算几何,好讨厌精度问题
这个计算几何挺简单的,我们只要枚举每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;
}
挺喜欢这种题,竟然忘记了筛法,哭了
问存在多少组能被整除的(本身除外),首先我们考虑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;
}