C. Urban Design
解题方法:这一题其实也不难,只要你画几个例子就很容易找到规律,但要注意的是我们用直线的一般式来判断两条直线是否相交,因为如果直接比较两条直线的斜率,会存在斜率求不出来的情况,这样比较复杂
#include<iostream>
using namespace std;
struct node{
double a;
double b;
double c;
}st[100010];
int n;
bool is_region(double x1,double y1,double x2,double y2){
int cnt=0;
for(int i=0;i<n;i++){
double a=st[i].a;
double b=st[i].b;
double c=st[i].c;
if((a*x1+b*y1+c)*(a*x2+b*y2+c) > 0){
continue;
}else{
cnt++;
}
}
if(cnt%2==0){
return false;
}else{
return true;
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
double A=y2-y1;
double B=x1-x2;
double C=x2*y1-x1*y2;
st[i].a=A;
st[i].b=B;
st[i].c=C;
}
int t;
cin>>t;
while(t--){
double x3,y3,x4,y4;
cin>>x3>>y3>>x4>>y4;
if(is_region(x3,y3,x4,y4)){
cout<<"different"<<endl;
}else{
cout<<"same"<<endl;
}
}
return 0;
}
G. Sheba's Amoebas
题意:本题就是要你判判断存在几个闭环
解题方法:dfs深搜即可,但要注意它找到起点的处理方法
#include<iostream>
#include<string.h>
using namespace std;
char ptr[150][150];
int vis[150][150];
int m,n;/*m行 n列*/
int ans=0;/*存储答案*/
int net[8][2]={{0,1},{0,-1},{1,0},{-1,0},{1,1},{-1,1},{-1,-1},{1,-1}};
bool check(int dx,int dy){
if(dx<0||dx>=m||dy<0||dy>=n){
return false;
}
if(ptr[dx][dy]=='#'&&vis[dx][dy]==0/*没有被访问过*/){//是黑色素 可行
return true;
}else{
return false;
}
}
bool check_c(int x,int y){//形成闭环
if(ptr[x][y]=='K'){/*找到了*/
ptr[x][y]='Y';
return true;
}else{
return false;
}
}
void dfs(int x,int y){/*传进去的是现在的位置,我们现在要找它的下一个位置*/
/*而且下一个位置它有 8 种可能*/
//下面我们寻找下一个位置
//判断是否形成闭环
for(int i=0;i<8;i++){/*判断其余几个方向还有没有路可以走*/
int dx=x+net[i][0];
int dy=y+net[i][1];
if(check(dx,dy)){//检测它是不是‘#’ 和坐标是否在合法范围内
vis[dx][dy]=1;/*标记被访问*/
ptr[dx][dy]='.';//标记该点被访问过
dfs(dx,dy);
}
}
for(int i=0;i<8;i++){
int dx1=x+net[i][0];
int dy1=y+net[i][1];/*下一个位置的坐标*/
if(check_c(dx1,dy1)){/*判断是否形成闭环的函数*/
ans++;
return ;
}
}
return ;
}
int main(){
cin>>m>>n;/*m行 n列*/
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
cin>>ptr[i][j];
}/*图的数量输入完毕,下面开始DFS操作*/
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(ptr[i][j]=='#'){//可以作为起点
vis[i][j]=1;/*标记已经被访问*/
ptr[i][j]='K';/*标记,这是开头,也就是起始点*/
dfs(i,j);//传进去开始的起点
}
}
}
cout<<ans<<endl;
return 0;
} H. Zebras and Ocelots
解题方法:快速幂,找规律
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
#define ll long long
ll quick_pow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res*=a;
a=a*a;
b=b>>1;
}
return res;
}
int main(){
ll n;/*动物的数量*/
char t;
cin>>n;
ll ans=0;
string ptr;
for(ll i=1;i<=n;i++){
cin>>t;
ptr=ptr+t;
}
string arr(ptr.rbegin(),ptr.rend());
for(ll i=0;i<arr.length();i++){
if(arr[i]=='O'){
ans=ans+quick_pow(2,i);
}
}
cout<<ans<<endl;
return 0;
} I. Racing Around the Alphabet
https://nanti.jisuanke.com/t/43376解题方法:简单模拟这个过程,每次取最短路径,注意pi的取值
#include<iostream>
using namespace std;
const double pi = 3.1415926535;
int main(){
int n;
cin>>n;
getchar();
while(n--){
int ans=0;
string s;
getline(cin,s);
for(int i=1;i<s.length();i++){
int a=s[i-1]-'A'+1;
int b=s[i]-'A'+1;
if(s[i-1]==' '){
a=27;
}else if(s[i-1]=='\''){
a=28;
}
if(s[i]==' '){
b=27;
}else if(s[i]=='\''){
b=28;
}
if(b<a){
int z=b;
b=a;
a=z;
}
int x1 = b-a;
int x2 = 28-(b-a);
ans+=min(x1,x2);
}
double zc = pi*60;
double jd = 1.0*zc/28*ans;
double sum = 1.0*jd/15+s.length();
printf("%.10f\n",sum);
}
return 0;
} J. Lost Map
https://nanti.jisuanke.com/t/43380解题方法:这一题主要考察最短路径的求法,只要你会这两个算法,并且还会熟练使用它,就不难
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
ll n;//村庄的数目
const ll max_n=3e10+10;
struct node{
int from,to;
ll cose;/*表示的是花费*/
}E[3000*3000];
int t;
//并查集的标准模板
int father[2525];//定义父节点
void uint(){//数组的初始化
for(int i=1;i<2525;i++){
father[i]=i;//认自己做父节点
}
}
int find_f(int x){//寻找父节点
if(x==father[x]){
return x;//返回父节点
}
return father[x]=find_f(father[x]);
}
void merge(int x,int y){
int p=find_f(x);
int q=find_f(y);
if(p!=q){
father[p]=q;//点 p 以点 q 做父节点
}
}
bool same(int x,int y){
return find_f(x)==find_f(y);//判断两者是否属于同一节点
}
bool cmp(node a,node b){
return a.cose<b.cose;//按花费的多少来排序
}
void Kluskal(){//实现克鲁斯卡尔算法
sort(E,E+t,cmp);
int num=0;
for(int i=0;i<t;i++){
if(same(E[i].from,E[i].to)){//如果这两者是互联互通的
// cout<<E[i].from<<" "<<E[i].to<<endl;
}else{//两者不是互通的
merge(E[i].from,E[i].to);
cout<<E[i].from<<" "<<E[i].to<<endl;
num++;
if(num==n-1){
break;
}
}
}
}
int main(){
cin>>n;
ll temp;
t=0;
uint();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
//下面的每个数输入的都是第 i 个城市与 第 j 个城市连接的代价
cin>>temp;
if(temp!=0){//如果他不是等于0
E[t].from=i;
E[t].to=j;
E[t++].cose=temp;//存储花费
}
}
}
Kluskal();
return 0;
} 


京公网安备 11010502036488号