結果

問題 No.635 自然門松列
ユーザー RisenRisen
提出日時 2018-01-19 22:28:26
言語 C#(csc)
(csc 3.9.0)
結果
WA  
実行時間 -
コード長 5,387 bytes
コンパイル時間 1,085 ms
コンパイル使用メモリ 111,104 KB
実行使用メモリ 19,584 KB
最終ジャッジ日時 2024-06-06 19:15:55
合計ジャッジ時間 2,283 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
権限があれば一括ダウンロードができます
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc)
Copyright (C) Microsoft Corporation. All rights reserved.

ソースコード

diff #

using System;
using System.Collections.Generic;
using System.Linq;

public struct Point
{
    public double X;
    public double Y;


    public Point(Point p)
    {
        X = p.X;
        Y = p.Y;
    }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public Point(double x, double y)
    {
        X = x;
        Y = y;
    }

    public static bool operator ==(Point a, Point b)
    {
        if ((object)a == null || (object)b == null)
        {
            if ((object)a == null && (object)b == null)
            {
                return true;
            }
            return false;
        }

        return (a.X == b.X && a.Y == b.Y);
    }

    public static bool operator !=(Point a, Point b)
    {
        if ((object)a == null || (object)b == null)
        {
            if ((object)a == null && (object)b == null)
            {
                return false;
            }
            return true;
        }

        return (a.X != b.X || a.Y != b.Y);
    }

    public static Point operator *(Point a, double i)
    {
        return new Point(a.X * i, a.Y * i);
    }

    public static Point operator /(Point a, double i)
    {
        return new Point(a.X / i, a.Y / i);
    }

    //objと自分自身が等価のときはtrueを返す
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }

        Point p = (Point)obj;
        return (X == p.X && Y == p.Y);
    }

    //Equalsがtrueを返すときに同じ値を返す
    public override int GetHashCode()
    {
        int prime = 31;
        int result = 1;
        long temp;
        temp = BitConverter.DoubleToInt64Bits(X);
        result = prime * result + (int)(temp ^ (temp >> 32));
        temp = BitConverter.DoubleToInt64Bits(Y);
        result = prime * result + (int)(temp ^ (temp >> 32));
        return result;
    }

    public Point Clone()
    {
        return new Point(X, Y);
    }

    public void Reverse()
    {
        X = -X;
        Y = -Y;
    }

    public static Point operator +(Point a, Point b)
    {
        return new Point(a.X + b.X, a.Y + b.Y);
    }

    public static Point operator -(Point a, Point b)
    {
        return new Point(a.X - b.X, a.Y - b.Y);
    }

    public static Point operator +(Point a)
    {
        return new Point(+a.X, +a.Y);
    }

    public static Point operator -(Point a)
    {
        return new Point(-a.X, -a.Y);
    }

    // 直線ABと直線CDの交点を求める
    // onlySegment:trueで線分ABと線分CDの交点を求める
    public static Point? GetCrossPoint(Point a, Point b, Point c, Point d, bool onlySegment = false)
    {
        double delta = (b.X - a.X) * (d.Y - c.Y) - (b.Y - a.Y) * (d.X - c.X);
        // 平行線
        if (delta == 0)
        {
            return null;
        }

        double u = ((c.X - a.X) * (d.Y - c.Y) - (c.Y - a.Y) * (d.X - c.X)) / delta;
        double v = ((c.X - a.X) * (b.Y - a.Y) - (c.Y - a.Y) * (b.X - a.X)) / delta;

        if (onlySegment)
        {
            // 線分AB内で交わらない
            if (u < 0.0 || u > 1.0)
            {
                return null;
            }
            // 線分CD内で交わらない
            if (v < 0.0 || v > 1.0)
            {
                return null;
            }
        }

        Point cross;
        cross.X = a.X + u * (b.X - a.X);
        cross.Y = a.Y + u * (b.Y - a.Y);

        // 誤差対策
        if (a.X == b.X)
        {
            cross.X = a.X;
        }
        else if (c.X == d.X)
        {
            cross.X = c.X;
        }
        if (a.Y == b.Y)
        {
            cross.Y = a.Y;
        }
        else if (c.Y == d.Y)
        {
            cross.Y = c.Y;
        }

        return cross;
    }
}

class Solution
{
    static bool WillPineDecoration(int[] array)
    {
        var start = array.Take(3).ToArray();
        var grow = array.Skip(3).ToArray();

        var line = new Tuple<Point, Point>[3];
        for (int i = 0; i < 3; i++)
        {
            line[i] = new Tuple<Point, Point>(new Point(0, start[i]), new Point(1, start[i] + grow[i]));
        }

        var time = new List<double> { 0 };
        foreach (int i in new int[] { 0, 2 })
        {
            var cross = Point.GetCrossPoint(line[i].Item1, line[i].Item2, line[1].Item1, line[1].Item2);
            if (cross != null && ((Point)cross).X > 0)
            {
                var e = 0.000001;
                time.Add(((Point)cross).X - e);
                time.Add(((Point)cross).X + e);
            }
        }

        foreach (var t in time)
        {
            var len = Enumerable.Range(0, 3).Select(i => start[i] + grow[i] * t).ToArray();
            if (len.Max() == len[1] || len.Min() == len[1])
            {
                if (len[0] != len[1] && len[1] != len[2])
                {
                    return true;
                }
            }
        }

        return false;
    }

    static void Main()
    {
        var n = int.Parse(Console.ReadLine());
        for (int i = 0; i < n; i++)
        {
            var array = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            if (WillPineDecoration(array))
            {
                Console.WriteLine("Yes");
            }
            Console.WriteLine("No");
        }
    }
}
0