Codeforces17A
题意:
有一种素数会等于两个相邻的素数相加
如果在2~n的范围内有至少k个这样的素数,就YES,否则就NO;
思路:
采用直接打表,后面判断一下就好了。那个预处理素数表还是满赞的~~
不多说,上code…………….
#include<bits/stdc++.h>
#include<string.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double eps=1e-5;
const double pi=acos(-1.0);
const int mod=1e8+7;
const LL INF=0x3f3f3f3f;
const int N=1e3+10;
bool isPrime[N];
int d[N];
int f[N];
void init()
{
fill(isPrime,isPrime+1001,true);
for(int i=2;i<=1000;i++)
{
if(!isPrime[i]) continue;
for(int j=i+i;j<1000;j+=i)
isPrime[j]=false;
}
int num=0;
for(int i=2;i<=1000;i++)
{
if(isPrime[i])
d[num++]=i;
}
memset(f,0,sizeof(f));
for(int i=0;i<num;i++){
for(int j=0;j+1<i;j++){
if(d[i]==(d[j]+d[j+1]+1))
{
// printf("%d+%d+1==%d\n",d[j],d[j+1],d[i]);
f[d[i]]=1;
}
}
}
}
int main()
{
int n,k;
init();
scanf("%d%d",&n,&k);
int sum=0;
for(int i=2;i<=n;i++)
{
if(isPrime[i])
{
if(f[i])
sum++;
}
}
if(sum>=k)
printf("YES\n");
else
printf("NO\n");
return 0;
}
Codeforces 18A
题意:
给你三个坐标,如果直接能构成RT三角形,输出”RIGHT“,
如果不能直接,能够移动一个点(只能上下左右,且只能移动1)就达到RT三角形,输出”ALMOST“,都不能输出”NEITHER“…….
思路:
真心水,但是一开始撒比搞了个求cos去了,其实只要比较三个平方就好了。(还有移动1只是上下左右……….讲道理我没看出说了是上下左右……..)
code…………
//#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double eps=1e-9;
const double pi=acos(-1.0);
const int mod=1e8+7;
const int INF=25000;
double dx[4]={0,0,-1,1};
double dy[4]={1,-1,0,0};
bool kill(double x1,double x2,double x3,double y1,double y2,double y3)
{
double ca,cc,cb;
double a,b,c;
a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
c=sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3));
if(fabs(a)<eps||fabs(b)<0||fabs(c)<0)
return 0;
ca=(b*b+c*c-a*a)/b/c*0.5;
cb=(c*c+a*a-b*b)/c/a*0.5;
cc=(a*a+b*b-c*c)/a/b*0.5;
//printf("%lf\n%lf\n%lf\n",ca,cb,cc);
if(fabs(ca)<eps||fabs(cb)<eps||fabs(cc)<eps)
return 1;
return 0;
}
int main()
{
double x1,x2,x3,y1,y2,y3;
double x[5],y[5];
double xx[5],yy[6];
for(int i=0;i<3;i++)
cin>>x[i]>>y[i];
if(kill(x[0],x[1],x[2],y[0],y[1],y[2])){
puts("RIGHT");
return 0;
}
for(int i=0;i<3;i++)
{
for(int j=0;j<4;j++)
{
int num=0;
xx[num]=x[i]+dx[j];
yy[num++]=y[i]+dy[j];
for(int k=0;k<3;k++){
if(i!=k){
xx[num]=x[k];
yy[num++]=y[k];
}
}
if(kill(xx[0],xx[1],xx[2],yy[0],yy[1],yy[2])){
puts("ALMOST");
return 0;
}
}
}
puts("NEITHER");
return 0;
}
Codeforces 17B
题意:
nick公司雇了N个人
qi为员工的资格。
m为收到的申请量。
收到m个application,有ai,bi,ci三个数。代表ai的官比bi大,但要花费ci;而且只有qai>qbi的时候才会合法。
建立一个合法的等级,还要使得cost最小。
思路:
利用d[i]数组直接转化坐标,然后就可以直接处理
保证下标之前的qi都是大于之后的,判断一下就好了。
code…………
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int eps=1e-9;
const int pi=acos(-1.0);
const int mod=1e6+7;
const int INF=1e6+1;
const int N=1e3+10;
struct asd{
int q;
int id;
};
asd p[N];
int d[N];
int ma[N][N];
bool cmp(asd x,asd y)
{
return x.q>y.q;
}
int main()
{
int n,m,i,j,a,b,c;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&p[i].q);
p[i].id=i;
}
sort(p+1,p+n+1,cmp);
for(i=1;i<=n;i++)
d[p[i].id]=i; //本来的编号=>排序后的编号
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
ma[i][j]=INF;
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
a=d[a]; //本来的编号=>排序后的编号
b=d[b];
ma[a][b]=min(c,ma[a][b]);
}
int ans=0;
for(i=2;i<=n;i++)
{
int mimi=INF;
for(j=1;j<i;j++)
{
if(p[j].q>p[i].q)
mimi=min(mimi,ma[j][i]);
}
if(mimi==INF)
{
puts("-1");
return 0;
}
ans+=mimi;
}
printf("%d\n",ans);
return 0;
}
Codeforces 20C
题意:
非常明白,输出1-n的一条最短路的路径,然后不能的话输出-1;
思路:
wa了。。。考虑到路的长度会爆long long但是没有去管INF的值,还是让他0X3F3F3F3F,后来就蜜汁RE28,讲道理RE28我是按照题目要求边数开的大小,然后还是要乘2否则蜜汁RE28,后来开大wa32,INF没改的锅。哎。。。菜啊+挫代码。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int eps=1e-9;
const int pi=acos(-1.0);
const int mod=1e8+7;
const LL INF=1e11;
const int N=1e5+10;
struct asd{
int to;
LL w;
int next;
};
asd q[N*2];
int tol,head[N*2];
int n,m;
int num[N],vis[N];
LL dis[N];
int pre[N];
queue<int>e;
void shuchu(int x)
{
if(pre[x]==-1){
printf("%d",x);
return;
}
shuchu(pre[x]);
printf(" %d",x);
}
void spfa(int s,int t)
{
for(int i=1;i<=n;i++)
{
dis[i]=INF;
vis[i]=num[i]=0;
}
pre[1]=-1;
dis[1]=0;
vis[1]=1;
while(!e.empty())
e.pop();
e.push(1);
while(!e.empty())
{
int u=e.front();
e.pop();
vis[u]=0;
for(int v=head[u];v!=-1;v=q[v].next)
{
int i=q[v].to;
if(dis[i]>dis[u]+q[v].w){
pre[i]=u;
dis[i]=dis[u]+q[v].w;
if(!vis[i]){
vis[i]=1;
e.push(i);
}
}
}
}
if(dis[n]!=INF)
shuchu(n);
else
puts("-1");
}
void init()
{
tol=0;
memset(head,-1,sizeof(head));
}
void add(int a,int b,LL c)
{
q[tol].to=b;
q[tol].w=c;
q[tol].next=head[a];
head[a]=tol++;
}
int main()
{
int a,b;
LL c;
scanf("%d%d",&n,&m);
init();
for(int i=0;i<m;i++)
{
scanf("%d%d%I64d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
spfa(1,n);
return 0;
}
Codeforces 17C
题意:
给你n长度的只含a,b,c三种字符的字符串
然后你可以每次执行一个操作:前面一个字符变成后面一个字符或者把后面的一个字符变成前面一个字符
问合法的串有多少个;
合法串的要求是字符a的数量,字符b的数量,字符c的数量,他们之间的数量差值不大于1
思路:
dp[i][j][k][l] := 前i个字符,a有j个,b有k个,c有l个的方案数
然后枚举第i个是变成前面的那个字符,还是变成后面的字符,累加就可以了。
n是150,对,jkl开到51就够了,i再开个滚动数组,2*51*51*51复杂度,还可以再去掉一维,因为l = n - i - j,所以l那一维不需要。dp[i][j][k] := 前i个字符,有j个a,k个b的方案数。
code……………..